有什么專門搜試卷做的網(wǎng)站app推廣平臺排行榜
當(dāng)畫面有自定義的表格或者樣式過于復(fù)雜的表格時,導(dǎo)出功能可以由前端實現(xiàn)
1. 使用的插件 : sheet.js-xlsx
文檔地址:https://docs.sheetjs.com/
中文地址:https://geekdaxue.co/read/SheetJS-docs-zh/README.md
xlsx-style:https://www.npmjs.com/package/xlsx-style
2. 安裝引用
安裝插件-vue3
yarn add xlsx
yarn add xlsx-style-vite (有樣式需求才需要安裝;背景色等)
引用插件
import * as XLSX from 'xlsx';
import * as XLSX_STYLE from 'xlsx-style-vite'
3. 組件表格的導(dǎo)出(無樣式)
以ant design vue 表格為例,只導(dǎo)出表格內(nèi)容
<a-table :columns="columns" :dataSource="detaildata" :scroll="{ x: 'max-content',y:700 }" ></table?>
<a-button @click="exportData">導(dǎo)出</a-button><script>//數(shù)據(jù)處理為數(shù)組const transData=(columns, tableList)=> {const obj = columns.reduce((acc, cur) => {if (!acc.titles && !acc.keys) {acc.titles = [];acc.keys = [];}acc.titles.push(cur.title);acc.keys.push(cur.dataIndex);return acc;}, {});const tableBody = tableList.map((item,i) => {return obj.keys.map((key,index) => item[key]);});return [ obj.titles, ...tableBody ];}const exportData=()=>{const tableData = transData(columns.value,detaildata.value);// 將數(shù)據(jù)數(shù)組轉(zhuǎn)換為工作表const ws = XLSX.utils.aoa_to_sheet(tableData);// 創(chuàng)建 workbookconst wb = XLSX.utils.book_new();ws['!ref'] = `A1:AI${tableData.length}`;//設(shè)置列寬ws["!cols"] = [{wpx: 120}, {wpx: 100},{wpx: 110},{wpx: 110},];//合并單元格ws['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }]// 將 工作表 添加到 workbookXLSX.utils.book_append_sheet(wb, ws, 'Sheet1');// 將 workbook 寫入文件XLSX.writeFile(wb, 'tablename.xlsx');}
</script>
3. 自定義表格的導(dǎo)出 (div拼成的表格)
比如這種前端拼成的,又附帶各種樣式的表格
一些常用的格式:
(1):合并單元格
(2):列寬
(3):背景色
(4):字體相關(guān)-大小粗細(xì)顏色字體等
(5):表格線,邊框
詳細(xì)的格式可以參考:
https://www.jianshu.com/p/869375439fee
https://www.npmjs.com/package/xlsx-style
數(shù)據(jù)處理就不寫了,數(shù)據(jù)處理為數(shù)組就可以了
const toExcel=()=>{const data = [['左上表頭','','','右上',''],['標(biāo)題1','','','',''],['標(biāo)題','測試合并','','',''],['固定標(biāo)題','123','123','',''],['左下表頭','','','右下',''],['2021','¥28337','測試數(shù)據(jù)','北京','黑龍江'],......]const worksheet = XLSX.utils.aoa_to_sheet([headers, ...data])const workbook = XLSX.utils.book_new()worksheet['!ref'] = `A1:AI${data.length}`//列寬 按excel的列順序排列,對應(yīng)A列,B列, C列......worksheet["!cols"] = [{wpx: 200}, {wpx: 80},{wpx: 80},{wpx: 110}, {wpx: 110},];/* 合并單元格 默認(rèn)合并當(dāng)前格的右側(cè)格子{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }A1 與 B1 合并 內(nèi)容為 A1 的內(nèi)容s:start 合并開始 e:end 合并結(jié)束r:row 行 c:col 列 */worksheet['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } },{ s: { r: 0, c: 4 }, e: { r: 0, c: 5 } },{ s: { r: 4, c: 0 }, e: { r: 4, c: 1 } },......];//表格詳細(xì)樣式for (let key in worksheet) {if (key == '!ref' || key == '!merges' || key == '!cols' || key == '!rows') {continue} else {//通過key值來選擇篩選想要的設(shè)置樣式的單元格if (key.substring(1)=='1'||key.substring(1)=='5'|| key == 'A2') {worksheet[key].s = { // 設(shè)置單元格樣式fill: { // 設(shè)置背景色fgColor: { rgb: 'F2F3F7' },},font: { // 設(shè)置字體name: '等線', // 字體名稱sz: 16, // 字體大小bold: true, // 字體是否加粗color:{ //字體顏色rgb:'ed263d'}},border:{ //設(shè)置邊框top: {style: 'thin',color:{rgb:'e5e7eb'}},bottom: {style: 'thin',color:{rgb:'e5e7eb'}}},alignment: {horizontal: 'center', // 橫向(向左、向右、居中)vertical: 'center', // 縱向(向上、向下、居中)wrapText: true, // 設(shè)置單元格自動換行,目前僅對非合并單元格生效indent: 0 // 設(shè)置單元格縮進(jìn)}}}else if(key == 'B1'){......}}}XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')const tmpDown = new Blob([s2ab(XLSX_STYLE.write(workbook, {bookType: 'xlsx',bookSST: false,type: 'binary',cellStyles: true,})),])downloadExcelFile(tmpDown, 'excelname' + '.xlsx')
}/*用到的方法*/
export function s2ab(s) {if (typeof ArrayBuffer !== 'undefined') {const buf = new ArrayBuffer(s.length)const view = new Uint8Array(buf);for (let i = 0; i != s.length; ++i) {view[i] = s.charCodeAt(i) & 0xff}return buf} else {const buf = new Array(s.length)for (let i = 0; i != s.length; ++i) {buf[i] = s.charCodeAt(i) & 0xff}return buf}
}/*** 使用 a 標(biāo)簽下載文件*/
export function downloadExcelFile(obj, fileName){const a_node = document.createElement('a')a_node.download = fileNameif ('msSaveOrOpenBlob' in navigator) {window.navigator.msSaveOrOpenBlob(obj, fileName)} else {a_node.href = URL.createObjectURL(obj)}a_node.click()setTimeout(() => {URL.revokeObjectURL(obj)}, 2000)
}
參考文章:https://blog.csdn.net/Cai181191/article/details/131130926