当前位置: 首页 > news >正文

延吉网站网站建设wordpress 树状目录结构

延吉网站网站建设,wordpress 树状目录结构,百度收录的网站多久更新一次,公司网站字体项目里经常用到的导出ecxel功能是默认导出一个sheet页 现在需要导出两个sheet,一个是总计,另一个是明细 效果如下: 我就在现有的单个导出的功能上改造了一下,只支持导出两个(代码不够灵活,如果需要多个&…

项目里经常用到的导出ecxel功能是默认导出一个sheet页
在这里插入图片描述
现在需要导出两个sheet,一个是总计,另一个是明细
效果如下:
在这里插入图片描述

我就在现有的单个导出的功能上改造了一下,只支持导出两个(代码不够灵活,如果需要多个,还需要再优化或直接手动往里面加)

1、导出按钮的点击事件中

 // 导出handleExport() {// 参数分别是:id数组(没用到,传空),sheet1名称,sheet2名称,sheet1表头,sheet2表头,sheet1数据源,sheet2数据源this.double_sheet_exportExcel('', 'xx统计','xx明细', this.columns,this.detailColumns, this.dataSource,this.detailDataSource)}

2、安装excel相关的库

npm install --save xlsx file-saver
npm install --save xlsx-style

3、在utils的公共js文件中,如common.js(自己项目定义的放公共方法的文件中)

export function double_sheet_exportExcel(ids, filename1,filename2, excelProps1, excelProps2, excelList1, excelList2, dictOptions = {}) {import('@/utils/export2Excel').then(excel => {// 处理第一个工作表的表头和数据const newExcelProps1 = JSON.parse(JSON.stringify(excelProps1))// 处理第一个工作表的表头newExcelProps1.forEach((prop, index) => {if (prop.visible === false || prop.field === 'operation') {newExcelProps1.splice(index, 1)}})const name = 'title'const tHeader1 = newExcelProps1.map(item => item[name]) // 第一个工作表的表头// 处理第一个工作表的数据let fileData1if (ids === undefined || ids.length === 0) {fileData1 = excelList1} else {let arr1 = JSON.parse(JSON.stringify(excelList1))let arrMap1 = new Map(arr1.map(obj => [obj.id, obj]))let resultArr1 = ids.map(id => arrMap1.get(id))fileData1 = resultArr1}fileData1.forEach(item => {newExcelProps1.forEach(v => {if (v.type === 'dict' && v.scopedSlots.content) {let dictField = v.dictField || ['dictValue', 'dictLabel']const filterData = dictOptions[v.field].filter(f => item[v.field] == f[dictField[0]])item[v.field] = !filterData.length ? '' : filterData[0][dictField[1]]}})})const data1 = fileData1.map(v => newExcelProps1.map(({ field }) => v[field]))// 处理第二个工作表的表头和数据const newExcelProps2 = JSON.parse(JSON.stringify(excelProps2))// 处理第二个工作表的表头newExcelProps2.forEach((prop, index) => {if (prop.visible === false || prop.field === 'operation') {newExcelProps2.splice(index, 1)}})const tHeader2 = newExcelProps2.map(item => item[name]) // 第二个工作表的表头// 处理第二个工作表的数据let fileData2if (ids === undefined || ids.length === 0) {fileData2 = excelList2} else {let arr2 = JSON.parse(JSON.stringify(excelList2))let arrMap2 = new Map(arr2.map(obj => [obj.id, obj]))let resultArr2 = ids.map(id => arrMap2.get(id))fileData2 = resultArr2}fileData2.forEach(item => {newExcelProps2.forEach(v => {if (v.type === 'dict' && v.scopedSlots.content) {let dictField = v.dictField || ['dictValue', 'dictLabel']const filterData = dictOptions[v.field].filter(f => item[v.field] == f[dictField[0]])item[v.field] = !filterData.length ? '' : filterData[0][dictField[1]]}})})const data2 = fileData2.map(v => newExcelProps2.map(({ field }) => v[field]))// 创建多 Sheet 的 Excel 文件const multiHeader = [[filename1], [filename2]] // 多 Sheet 的标题const merges = [[`A1:${numToEng(newExcelProps1.length)}1`], // 第一个 Sheet 的合并单元格[`A1:${numToEng(newExcelProps2.length)}1`], // 第二个 Sheet 的合并单元格]
const filename = filename1excel.double_sheet_export_json_to_excel({title: [],multiHeader, // 多 Sheet 的标题header: [tHeader1, tHeader2], // 每个 Sheet 的表头data: [data1, data2], // 每个 Sheet 的数据merges, // 合并单元格filename, // 文件名autoWidth: true, // 自动宽度bookType: 'xlsx', // 文件格式sheetName: [filename1, filename2], // 每个 Sheet 的名称})})
}

4、在main.js中全局挂载

import {double_sheet_exportExcel,}Vue.prototype.double_sheet_exportExcel = double_sheet_exportExcel

5、在utils中新建ecport2Excel.js

export function double_sheet_export_json_to_excel({title,multiHeader = [],header,data,filename,departName = [],merges = [], // 二维数组,每个子数组对应一个 Sheet 的合并单元格autoWidth = true,bookType = 'xlsx',sheetName = ['Sheet1'], // 每个 Sheet 的名称exportAlignleft,
} = {}) {const wb = new Workbook()// 确保 header 和 data 是数组的数组(多 Sheet 支持)if (!Array.isArray(header[0])) {header = [header]}if (!Array.isArray(data[0])) {data = [data]}if (!Array.isArray(merges[0])) {merges = [merges]}header.forEach((sheetHeader, index) => {const sheetData = data[index] || []const sheetMerges = merges[index] || []const ws_name = sheetName[index] || `Sheet${index + 1}`const doubleMutiHeader = multiHeader[index]// console.log('sheetHeader:', sheetHeader)// console.log('sheetData:', sheetData)// 构造工作表数据const ws_data = [...title, ...departName, doubleMutiHeader, sheetHeader, ...sheetData]// 创建工作表const ws = double_sheet_from_array_of_arrays(ws_data)// 处理合并单元格if (sheetMerges && sheetMerges.length > 0) {if (!ws['!merges']) ws['!merges'] = []sheetMerges.forEach(item => {try {ws['!merges'].push(XLSX.utils.decode_range(item))} catch (e) {console.error(`Invalid merge range: ${item}`, e)}})}// 设置列宽if (autoWidth) {const validRows = ws_data.filter(row => Array.isArray(row) && row.length > 0)const colWidth = validRows.map(row => {return row.map(val => {if (val == null || val === '') {return { wch: 40 } // 默认宽度} else if (val.toString().charCodeAt(0) > 255) {return { wch: val.toString().length * 5 } // 中文字符宽度} else {return { wch: val.toString().length * 1 } // 英文字符宽度}})})// let result = colWidth[1] || []原先取的是colWidth[0],打印发现colWidth[0]只有一项,应该是colWidth[1],长度同列表总列数let result = colWidth[1] || []for (let i = 1; i < colWidth.length; i++) {for (let j = 0; j < colWidth[i].length; j++) {if (result[j]?.wch < colWidth[i][j].wch) {result[j] = colWidth[i][j]}}}// ws['!cols'] = result//  ws['!cols'],假如导出共有7列,格式:[{wch:25},{wch:45},{wch:25},{wch:25},{wch:25},{wch:25},{wch:25}]ws['!cols'] = result.map(col => {return { wch: col.wch }})}// 设置单元格样式const borderAll = {top: { style: 'thin' },bottom: { style: 'thin' },left: { style: 'thin' },right: { style: 'thin' },}const dataInfo = wsconst row = ['!ref', '!merges', '!cols']for (var i in dataInfo) {if (row.indexOf(i) === -1) {if (exportAlignleft == 'exportAlignleft') {dataInfo[i].s = {border: borderAll,alignment: { horizontal: 'left', vertical: 'center' },}} else {if (dataInfo[i].t == 'n') {dataInfo[i].s = {border: borderAll,alignment: { horizontal: 'right', vertical: 'center' },}} else {dataInfo[i].s = {border: borderAll,alignment: { horizontal: 'center', vertical: 'center' },}}}}}// 添加工作表到工作簿wb.SheetNames.push(ws_name)wb.Sheets[ws_name] = ws// 根据表头长度生成单元格列数组const arr = generateHeaderArr(header[0].length)// 表头加上样式arr.forEach(v => {let v2 = v + '2'if (dataInfo.hasOwnProperty(v2)) {dataInfo[v2].s = {border: borderAll,font: {color: { rgb: 'FFFFFF' },bold: false,italic: false,underline: false,},alignment: {horizontal: 'center',vertical: 'center',},fill: {fgColor: { rgb: '808080' },},}}})//设置主标题样式dataInfo['A1'].s = {font: {name: '微软雅黑',sz: 16,color: { rgb: '000000' },bold: false,italic: false,underline: false,},alignment: {horizontal: 'center',vertical: 'center',},}})// 导出 Excel 文件const wbout = XLSX.write(wb, {bookType: bookType,bookSST: false,type: 'binary',})saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream',}),`${filename}.${bookType}`)
}
function double_sheet_from_array_of_arrays(data, opts) {var ws = {}var range = {s: { c: 10000000, r: 10000000 }, // 初始化范围的起始点e: { c: 0, r: 0 }, // 初始化范围的结束点}// 确保 data 是一个数组if (!Array.isArray(data)) {console.error('Data is not an array:', data)return ws}for (var R = 0; R < data.length; ++R) {// 确保 data[R] 是一个数组if (!Array.isArray(data[R])) {console.warn('Row', R, 'is not an array:', data[R])continue // 跳过非数组行}for (var C = 0; C < data[R].length; ++C) {if (range.s.r > R) range.s.r = Rif (range.s.c > C) range.s.c = Cif (range.e.r < R) range.e.r = Rif (range.e.c < C) range.e.c = Cvar cell = { v: data[R][C] }if (cell.v == null) continuevar cell_ref = XLSX.utils.encode_cell({ c: C, r: R })if (typeof cell.v === 'number') cell.t = 'n'else if (typeof cell.v === 'boolean') cell.t = 'b'else if (cell.v instanceof Date) {cell.t = 'd'cell.z = XLSX.SSF._table[14]cell.v = datenum(cell.v)} else cell.t = 's'ws[cell_ref] = cell}}if (range.s.c < 10000000) {ws['!ref'] = XLSX.utils.encode_range(range)}return ws
}
// 迭代生成单元格表头数组
function generateHeaderArr(length) {const result = []const generator = generateHeaderString()for (let i = 0; i < length; i++) {const nextString = generator.next().valueresult.push(nextString)}return result
}
// 生成器
function* generateHeaderString() {let index = 0const letterString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'while (true) {let str = ''let n = indexwhile (n >= 0) {str = letterString[n % 26] + strn = Math.floor(n / 26) - 1}yield strindex++}
}
function Workbook() {if (!(this instanceof Workbook)) return new Workbook()this.SheetNames = []this.Sheets = {}
}
function datenum(v, date1904) {if (date1904) v += 1462var epoch = Date.parse(v)return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
}
function s2ab(s) {var buf = new ArrayBuffer(s.length)var view = new Uint8Array(buf)for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xffreturn buf
}
http://www.dtcms.com/a/574333.html

相关文章:

  • 高端定制站开发立网站系
  • 本溪市城乡住房建设厅网站郑州建设局官网
  • 发那科机器人在氩弧焊中搭配节气装置的优势
  • 开发者实践:机器人梯控的 API 对接与 MQTT 边缘调度解耦
  • 永康市网站建设制作网站模板超市
  • UE5.6 玻璃材质——Lumen
  • UE5 AI行为树源码解析(Composites)
  • 做婚庆网站安徽元鼎建设工程网站
  • 建设银行注册网站首页php网站服务器搭建
  • 织梦网站如何转百度小程序同步网络营销策略和方法
  • UE5 C++ Slate 画曲线
  • 【机器学习15】强化学习入门、Q-Learning、贝尔曼方程
  • 解释seo网站推广北京十大科技公司
  • 基于电鱼 AI 工控机的塔吊与升降机安全监测方案——实时采集传感器数据,AI智能判断异常并报警
  • 如何看一个网站用什么程序做的南开做网站
  • 京东云双11活动-云产品特惠热卖中
  • 企业网站如何seowordpress touch
  • 怎样进行网站板块建设支付宝网站登录入口
  • Harbor 私有镜像仓库安装教程
  • 批发/贸易企业数字化转型:PHP开发的B2B订货系统
  • ACMMM2025 |TGSI+SATL:不改模型架构也能提升预测性能,破解几何结构评估与建模难题!
  • 【笔记】Windows系统安装SAM-2(Segment Anything Model 2)
  • 宁波网站制作报价主题设置wordpress
  • 嵌入式Linux安全启动全解析:从原理到实战
  • wordpress培训类网站模板厦门软件开发培训机构
  • 16000+字!Java集合笔记
  • 中国免费域名申请网站色彩搭配的网站
  • 传播网站建设龙泉驿最新消息
  • 2.2 python中带参数的装饰器与类装饰器
  • Java程序导致CPU打满如何排查