vue項目中,純前端實現(xiàn)jexcel導(dǎo)出(樣式+單元格格式)

? ? ? ? 免費開源的框架jexcel(jexcel文檔),他自帶的導(dǎo)出沒什么問題,就是格式和單元格的格式不太好,報表中的背景色等都沒有,所以決定找個方法做導(dǎo)出報表功能。廢話不多說,直接上代碼。

? ? ? ? 首先,先把封裝的導(dǎo)出js文件中引用的方法奉上:

// 去除千分位 num -> 字符串格式

export function delCommafy(num) {

? ? if ((num + '').trim() === '') {

? ? ? ? return ''

? ? }

? ? if (isType(num, 'string')) {

? ? ? ? num = num.replace(/,/gi, '')

? ? }

? ? return num

}

// 把reg(255,255,255)轉(zhuǎn)為16進制顏色(無#號)

export function colorHex(color) {

? ? // RGB顏色值的正則

? ? var reg = /^(rgb|RGB)/

? ? if (reg.test(color)) {

? ? ? ? // ? var strHex = "#";

? ? ? ? var strHex = ''

? ? ? ? var colorArr = color.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')

? ? ? ? for (var i = 0; i < colorArr.length; i++) {

? ? ? ? ? ? var hex = Number(colorArr[i]).toString(16)

? ? ? ? ? ? if (hex === '0') {

? ? ? ? ? ? ? ? hex += hex

? ? ? ? ? ? }

? ? ? ? ? ? strHex += hex

? ? ? ? }

? ? ? ? return strHex

? ? } else {

? ? ? ? return color

? ? }

}

? ? ? ? 其次就是封裝的導(dǎo)出方法了:

import { colorHex, delCommafy } from '@/utils/index'

import XLSX from 'xlsx-style'

/**

?*

?* @param {string} fileNames 導(dǎo)出文件名

?* @param {string} exportType 導(dǎo)出類型(xlsx...)

?* @param {object} jexcel jexcel對象

?* @param {object} jexcelSpread jexcel的spread對象

?*/

export function exportReports(fileNames, exportType, jexcel, jexcelSpread) {

? ? function saveAs(obj, fileName) {

? ? ? ? var tmpa = document.createElement('a')

? ? ? ? tmpa.download = fileName || '下載'

? ? ? ? tmpa.href = URL.createObjectURL(obj)

? ? ? ? tmpa.click()

? ? ? ? setTimeout(function() {

? ? ? ? ? ? URL.revokeObjectURL(obj)

? ? ? ? }, 100)

? ? }

? ? const wopts = { bookType: 'xlsx', bookSST: true, type: 'binary', cellStyles: true }

? ? function downloadExl(fileName, type) {

? ? ? ? let datas = jexcelSpread.getData()

? ? ? ? let merges = jexcelSpread.getMerge()

? ? ? ? let styles = jexcelSpread.getStyle()

? ? ? ? let exportData = [] //用來保存轉(zhuǎn)換好的json

? ? ? ? exportData['!merges'] = []

? ? ? ? exportData['!cols'] = []

? ? ? ? exportData['!rows'] = []

? ? ? ? datas.forEach((rowData, rowIndex) => {

? ? ? ? ? ? rowData.forEach((colData, colIndex) => {

? ? ? ? ? ? ? ? exportData[jexcel.getColumnNameFromId([colIndex, rowIndex])] = {

? ? ? ? ? ? ? ? ? ? v: Number(delCommafy(colData)) ? delCommafy(colData) : colData,

? ? ? ? ? ? ? ? }

? ? ? ? ? ? })

? ? ? ? })

? ? ? ? for (const key in merges) {

? ? ? ? ? ? let startMergeId = jexcel.getIdFromColumnName(key).split('-')

? ? ? ? ? ? let startCol = Number(startMergeId[0])

? ? ? ? ? ? let startRow = Number(startMergeId[1])

? ? ? ? ? ? let endCol = startCol + (merges[key][0] - 1)

? ? ? ? ? ? let endRow = startRow + (merges[key][1] - 1)

? ? ? ? ? ? exportData['!merges'].push({

? ? ? ? ? ? ? ? s: {

? ? ? ? ? ? ? ? ? ? r: startRow,

? ? ? ? ? ? ? ? ? ? c: startCol,

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? e: {

? ? ? ? ? ? ? ? ? ? r: endRow,

? ? ? ? ? ? ? ? ? ? c: endCol,

? ? ? ? ? ? ? ? },

? ? ? ? ? ? })

? ? ? ? }

? ? ? ? for (const key in styles) {

? ? ? ? ? ? let styleArr = styles[key].split(';').map(item => item.replaceAll(' ', ''))

? ? ? ? ? ? let fgRgb = styleArr.filter(item => item.indexOf('background-color') === 0).length

? ? ? ? ? ? ? ? ? colorHex(

? ? ? ? ? ? ? ? ? ? ? styleArr

? ? ? ? ? ? ? ? ? ? ? ? ? .filter(item => item.indexOf('background-color') === 0)[0]

? ? ? ? ? ? ? ? ? ? ? ? ? .replace('background-color:', ''),

? ? ? ? ? ? ? ? ? )

? ? ? ? ? ? ? ? : 'FFFFFF'

? ? ? ? ? ? const borderAll = {

? ? ? ? ? ? ? ? //單元格外側(cè)框線

? ? ? ? ? ? ? ? top: {

? ? ? ? ? ? ? ? ? ? style: 'thin',

? ? ? ? ? ? ? ? ? ? color: { rgb: colorHex('rgb(204,204,204)') },

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? bottom: {

? ? ? ? ? ? ? ? ? ? style: 'thin',

? ? ? ? ? ? ? ? ? ? color: { rgb: colorHex('rgb(204,204,204)') },

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? left: {

? ? ? ? ? ? ? ? ? ? style: 'thin',

? ? ? ? ? ? ? ? ? ? color: { rgb: colorHex('rgb(204,204,204)') },

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? right: {

? ? ? ? ? ? ? ? ? ? style: 'thin',

? ? ? ? ? ? ? ? ? ? color: { rgb: colorHex('rgb(204,204,204)') },

? ? ? ? ? ? ? ? },

? ? ? ? ? ? }

? ? ? ? ? ? exportData[key].s = {

? ? ? ? ? ? ? ? border: borderAll,

? ? ? ? ? ? ? ? fill: {

? ? ? ? ? ? ? ? ? ? bgColor: { indexed: 64 },

? ? ? ? ? ? ? ? ? ? fgColor: { rgb: fgRgb },

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? alignment: {

? ? ? ? ? ? ? ? ? ? vertical: 'center',

? ? ? ? ? ? ? ? ? ? wrapText: true,

? ? ? ? ? ? ? ? },

? ? ? ? ? ? }

? ? ? ? ? ? // 設(shè)置單元格類型(n:數(shù)值,s:字符串)

? ? ? ? ? ? let judgeCondition =

? ? ? ? ? ? ? ? (String(exportData[key].v).includes('.') && Number(exportData[key].v)) || !exportData[key].v

? ? ? ? ? ? exportData[key].t = judgeCondition ? 'n' : 's'

? ? ? ? ? ? // 數(shù)值格式(二選一)

? ? ? ? ? ? exportData[key].z = judgeCondition ? '#,##0.00;-#,##0.00' : ''

? ? ? ? }

? ? ? ? let colsLen = jexcelSpread.colgroup.length

? ? ? ? for (let j = 0; j < colsLen; j++) {

? ? ? ? ? ? exportData['!cols'].push({ wpx: Number(jexcelSpread.getWidth()[j]) })

? ? ? ? }

? ? ? ? exportData['!cols'].push({ wpx: 100 })

? ? ? ? let outputPos = Object.keys(exportData) //設(shè)置區(qū)域,比如表格從A1到D10

? ? ? ? var tmpWB = {

? ? ? ? ? ? SheetNames: ['mySheet'], //保存的表標(biāo)題

? ? ? ? ? ? Sheets: {

? ? ? ? ? ? ? ? mySheet: Object.assign(

? ? ? ? ? ? ? ? ? ? {},

? ? ? ? ? ? ? ? ? ? exportData, //內(nèi)容

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? '!ref': outputPos[3] + ':' + outputPos[outputPos.length - 1], //設(shè)置填充區(qū)域

? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ),

? ? ? ? ? ? },

? ? ? ? }

? ? ? ? let tmpDown = new Blob(

? ? ? ? ? ? [

? ? ? ? ? ? ? ? s2ab(

? ? ? ? ? ? ? ? ? ? XLSX.write(

? ? ? ? ? ? ? ? ? ? ? ? tmpWB,

? ? ? ? ? ? ? ? ? ? ? ? { bookType: type == undefined ? 'xlsx' : type, bookSST: false, type: 'binary' }, //這里的數(shù)據(jù)是用來定義導(dǎo)出的格式類型

? ? ? ? ? ? ? ? ? ? ),

? ? ? ? ? ? ? ? ),

? ? ? ? ? ? ],

? ? ? ? ? ? {

? ? ? ? ? ? ? ? type: '',

? ? ? ? ? ? },

? ? ? ? )

? ? ? ? saveAs(tmpDown, fileName + '.' + (wopts.bookType == 'biff2' ? 'xlsx' : wopts.bookType))

? ? }

? ? function s2ab(s) {

? ? ? ? if (typeof ArrayBuffer !== 'undefined') {

? ? ? ? ? ? let buf = new ArrayBuffer(s.length)

? ? ? ? ? ? let view = new Uint8Array(buf)

? ? ? ? ? ? for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff

? ? ? ? ? ? return buf

? ? ? ? } else {

? ? ? ? ? ? let buf = new Array(s.length)

? ? ? ? ? ? for (let i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff

? ? ? ? ? ? return buf

? ? ? ? }

? ? }

? ? downloadExl(fileNames, exportType)

}

? ? ? ? vue中引入傳參調(diào)用就可以了:

????????????????????? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? type: 'i',

? ? ? ? ? ? ? ? ? ? ? ? ? ? content: 'cloud_download',

? ? ? ? ? ? ? ? ? ? ? ? ? ? onclick: (element, instance) => {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? let fileNames = '導(dǎo)出'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? exportReports(fileNames, 'xlsx', jexcel, instance)

? ? ? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? 報表原來的頁面展示:


? ? ? ? 導(dǎo)出效果(背景色及單元格格式都有):


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容