pdfMake,xlsx-js-style,elementTable表格导出大量数据的pdf和xslx表格

 使用渲染dom传递给xlsx或将dom转canvas在传给jspdf数据量大都会造成页面负载过大

所以导pdf和xlsx都使用数据传递给pdfMake,xlsx-js-style,pdf涉及分页与合并单元格

 一.pdf

npm并引入pdfMake和其字体包(记录时使用版本0.2.10

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";

 官网地址pdfmake

pdfMake支持表格和列表等传递数据类型导出pdf,支持水印与合并行列单元格,支持字体颜色和简单样式设置

1.引入中文字体包

pdfMake自带的roboto字体不支持中文,所以需要自己下载一个支持中文的ttf文件,这里使用

SourceHanSansCN-Normal.ttf,网上下载该文件资源,在node_modules的pdfMake包中新建examples

文件夹,在examples中新建一个fonts文件夹,将需要的字体包复制进去。

在pdfMake的目录下打开控制台或者cmd等命令行运行命令,pdfmake会构建字体的编码到pdfmake下的/build/vfs_fonts.js中,这个文件应该包含四种roboto字体

node build-vfs.js "./examples/fonts"

2.引入字体出现错误

pdfmake Font 'Roboto' in style 'bold' is not defined in the font section of或

File 'Roboto-Regular.ttf' not found in virtual file system,等问题

pdfmake Font ‘Roboto‘ in style ‘bold‘ is not defined in the font section of或File ‘Roboto-Regular.t-CSDN博客

3.使用pdfMake的数据格式

contect =	{style: 'tableExample',color: '#444',table: {
//每行宽度widths: [200, 'auto', 'auto'],
//表头的行数,设置为表头分页时会携带headerRows: 2,// keepWithHeaderRows: 1,
//table的数据,合并Colspan ,rowspanbody: [[{text: 'Header with Colspan = 2', style: 'tableHeader', colSpan: 2, alignment: 'center'}, {}, {text: 'Header 3', style: 'tableHeader', alignment: 'center'}],[{text: 'Header 1', style: 'tableHeader', alignment: 'center'}, {text: 'Header 2', style: 'tableHeader', alignment: 'center'}, {text: 'Header 3', style: 'tableHeader', alignment: 'center'}],['Sample value 1', 'Sample value 2', 'Sample value 3'],[{rowSpan: 3, text: 'rowSpan set to 3\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor'}, 'Sample value 2', 'Sample value 3'],['', 'Sample value 2', 'Sample value 3'],['Sample value 1', 'Sample value 2', 'Sample value 3'],['Sample value 1', {colSpan: 2, rowSpan: 2, text: 'Both:\nrowSpan and colSpan\ncan be defined at the same time'}, ''],['Sample value 1', '', ''],]}},let pdfMakeData = {// watermark: { text: '乐恒', font: 'SourceHanSansCN' } || '',pageSize: pageSize,// pageOrientation: 'portrait',pageMargins: [cardLeft,cardTop,cardLeft,cardTop,],content: content,
//简单的样式styles: {tableExample: {margin: [0, 5, 0, 15],font: 'SourceHanSansCN',color: 'black',},},defaultStyle: {defaultStyle: {font: 'SourceHanSansCN'},}}
//业务逻辑结束,根据需要构建pdfMake需要的content
//添加vfs字体pdfMake.vfs = pdfFonts;
//添加字体对象,Roboto是必须添加的否则报错,剩余添加需要的字体这里是SourceHanSansCNpdfMake.fonts = {Roboto: {normal: 'Roboto-Regular.ttf',bold: 'Roboto-Medium.ttf',italics: 'Roboto-Italic.ttf',bolditalics: 'Roboto-MediumItalic.ttf'},SourceHanSansCN: {normal: 'SourceHanSansCN-Normal.ttf',bold: 'SourceHanSansCN-Normal.ttf',italics: 'SourceHanSansCN-Normal.ttf',bolditalics: 'SourceHanSansCN-Normal.ttf'}};
//下载pdfMake.createPdf(pdfMakeData).download(getFileName());

 4.使用pdfMake下载

function downPDF({ dataList, labelList, spanObj }) {
//设置一些活参数有用的是oneRowNum每页需要多少列,oneCellWidth每个单元格宽度,纸张型号宽高let cardTop = 10, cardLeft = 7, textLeft = 9, textTop = 14, oneColumnNum = 35, oneRowNum = 7, oneCellWidth = 73.7, oneCellHeight = 8, oneStrLen = 5, pdfWidth = 203, pdfHeight = 290, strLen = 8, pageSize = 'A4'
//我的业务逻辑实现开始(分页,合并单元格let startIndex = 0, endIndex = oneRowNumlet content = []let columnPages = Math.ceil(dataList.length / oneRowNum) + 1for (let i = 1; i < columnPages; i++) {let currentColumnData = dataList.slice((i - 1) * oneRowNum, i * oneRowNum)let currentLabelData = labelList.slice((i - 1) * oneRowNum, i * oneRowNum)let ownObj = {table: {headerRows:spanObj.rowIndex[1],widths: new Array(currentLabelData.length).fill(oneCellWidth),body: [// [{text: 'Header 1'}, {text: 'Header 2', style: 'tableHeader'}, {text: 'Header 3', style: 'tableHeader'}],// ['Sample value 1', 'Sample value 2', 'Sample value 3'],],},style: 'tableExample'}let headerArr = []currentLabelData.forEach((item) => {headerArr.push({ text: item })})let columnArr = new Array()currentColumnData.forEach((item, index) => {item.forEach((cItem, cIndex) => {columnArr[cIndex] = columnArr[cIndex] || []columnArr[cIndex].push(cItem)})})if (i === 1) {spanObj.columnIndex.forEach((item, index) => {for (let cindex = 0; cindex < columnArr.length; cindex++) {const cItem = columnArr[cindex];let cChild = cItem[item]if (cChild) {let repeatIndex = columnArr.filter((fItem) => {return fItem[item] === cChild}).lengthcItem[item] = { text: cChild, rowSpan: repeatIndex }index = repeatIndex + index - 1}}})}columnArr.unshift(headerArr)if (spanObj.rowIndex[0].length !== 0) {let rowHead = []let endLen = i + 1 === columnPages ? (dataList.length - (i - 1) * oneRowNum) : oneRowNumfor (let keyIndex = 0; keyIndex < endLen; keyIndex++) {let rowCurrent = (i - 1) * oneRowNum + keyIndexlet rowEnd = 0for (const key in spanObj.rowIndex[0]) {let children = spanObj.rowIndex[0][key]rowEnd = rowEnd + children.lengthif (rowEnd > rowCurrent) {let obj = { text: key }rowHead.push(obj)break;}}}for (let index = 0; index < rowHead.length; index++) {const cItem = rowHead[index];let repeatIndex = rowHead.filter((fItem) => {return fItem.text === cItem.text}).lengthrowHead[index].colSpan = repeatIndexindex = repeatIndex + index - 1}columnArr.unshift(rowHead)}ownObj.table.body = columnArrcontent.push(ownObj)}console.log('content', JSON.parse(JSON.stringify(content)))
//业务逻辑结束,根据需要构建pdfMake需要的content
//添加vfs字体pdfMake.vfs = pdfFonts;
//添加字体对象,Roboto是必须添加的否则报错,剩余添加需要的字体这里是SourceHanSansCNpdfMake.fonts = {Roboto: {normal: 'Roboto-Regular.ttf',bold: 'Roboto-Medium.ttf',italics: 'Roboto-Italic.ttf',bolditalics: 'Roboto-MediumItalic.ttf'},SourceHanSansCN: {normal: 'SourceHanSansCN-Normal.ttf',bold: 'SourceHanSansCN-Normal.ttf',italics: 'SourceHanSansCN-Normal.ttf',bolditalics: 'SourceHanSansCN-Normal.ttf'}};
//创建打印数据对象let pdfMakeData = {// watermark: { text: '乐恒', font: 'SourceHanSansCN' } || '',pageSize: pageSize,// pageOrientation: 'portrait',pageMargins: [cardLeft,cardTop,cardLeft,cardTop,],content: content,
//简单的样式styles: {tableExample: {margin: [0, 5, 0, 15],font: 'SourceHanSansCN',color: 'black',},},defaultStyle: {defaultStyle: {font: 'SourceHanSansCN'},}}//下载pdfMake.createPdf(pdfMakeData).download(getFileName());
}

GitHub - bpampuch/pdfmake: Client/server side PDF printing in pure JavaScript

二.xlsx

1.npm下载并引入xlsx-js-style,它比xlsx支持自定义表格style,即用数据和属性可以构建xlsx的下载不传dom只操作数据

import XLSX from "xlsx-js-style";

2.下载函数,整理获取到的table数据,根据需求填充,需求只涉及二级表头的合并行与前几列的合并,并非整个表格合并

//表格数据数据,表头数据数组,合并行列数组
function downXlsx({ dataList, labelList, spanObj }) {
console.log(dataList, labelList, spanObj)
//添加合并列的单元格let mergesArr = []spanObj.columnIndex.forEach((item, index) => {for (let cindex = 0; cindex < dataList.length; cindex++) {const cItem = dataList[cindex];let cChild = cItem[item]if (cChild) {let repeatIndex = dataList.filter((fItem) => {return fItem[item] === cChild}).lengthmergesArr.push({ s: { r: cindex + 1, c: item }, e: { r: cindex + repeatIndex, c: item } })cindex = repeatIndex + cindex - 1}}})
//添加表头为第一列dataList.unshift(labelList)
//添加合并列的单元格(二级表头if (spanObj.rowIndex[0].length !== 0) {let rowHead = []for (let keyIndex = 0; keyIndex < labelList.length; keyIndex++) {let rowEnd = 0for (const key in spanObj.rowIndex[0]) {let children = spanObj.rowIndex[0][key]rowEnd = rowEnd + children.lengthif (rowEnd > keyIndex) { rowHead.push(key)break;}}}for (let index = 0; index < rowHead.length; index++) {const cItem = rowHead[index];let repeatIndex = rowHead.filter((fItem) => {return fItem === cItem}).lengthmergesArr.push({ s: { r: 0, c: index }, e: { r: 0, c: index + repeatIndex-1 } })index = repeatIndex + index - 1}dataList.unshift(rowHead)}
//创建xlsx,下载const wb = XLSX.utils.book_new();const ws = XLSX.utils.json_to_sheet(dataList, {skipHeader: true,});ws["!merges"] = mergesArr;XLSX.utils.book_append_sheet(wb, ws, "Sheet1");XLSX.writeFile(wb, getFileName());
}

spanObj的数据格式

//datalist每个元素的数据是table的行数据
datalist:[[],[],[]]
labelList:["名称","事件","ey位m","温度℃""]
spanObj :{
//多级表头,一级表头属性下的二级表头内容"rowIndex": [{"基础信息": [{"label": "名称","prop": "MingCheng","width": "150","click": "rezhan"},{"label": "事件","prop": "事件","width": "150","click": "rezhan"},],"xx数据": [{"label": "ey位m","prop": "shuiXiangYeWei","width": "100","fixed": 1},],"其他数据": [{"label": "温度℃","prop": "shiWaiWenDu","width": "110","fixed": 1},]},2],
//第0列需要合并,合并相同内容"columnIndex": [0]
}

 html简单demo,fonts里有字体运行index即可

pdfxlsx: 不操作dom导出pdf xlsxxlsx-js-style pdfmake

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/706382.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六西格玛绿带培训:解锁质量工程师的职场新篇章

在质量管理这条道路上&#xff0c;我们或许都曾有过这样的疑问&#xff1a;为何付出了同样的努力&#xff0c;却未能获得预期的回报&#xff1f;当我们看到身边的同行们逐渐步入高薪的行列&#xff0c;而自己却似乎陷入了职业的泥沼&#xff0c;这种对比无疑令人倍感焦虑。然而…

【SRC实战】退款导致零元购支付漏洞

挖个洞先 https://mp.weixin.qq.com/s/3k3OCC5mwI5t9ILNt6Q8bw “ 以下漏洞均为实验靶场&#xff0c;如有雷同&#xff0c;纯属巧合 ” 01 — 漏洞证明 1、购买年卡会员 2、订单处查看已支付 3、申请退款 4、会员仍然有效 5、使用另一个账号重复支付退款操作&#…

「AIGC算法」近邻算法原理详解

本文主要介绍近邻算法原理及实践demo。 一、原理 K近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;是一种基于距离的分类算法&#xff0c;其核心思想是距离越近的样本点&#xff0c;其类别越有可能相似。以下是KNN算法的原理详解&#xff1a; 1. 算…

在Python中防止某些字段被Pickle序列化

在Python中&#xff0c;如果你想防止某些字段被pickle序列化&#xff0c;可以使用__reduce__()方法来自定义pickle行为。__reduce__()方法允许你返回一个元组&#xff0c;其中包含要在对象被pickle时调用的函数以及传递给该函数的参数。下面就是我遇到的问题以及最终解决方案。…

PCIE/PCI设备配置空间

PCI/PCIE Capability PCI/PCIE设备的配置空间记录了PCIE设备的capability支持信息&#xff0c;每个capability定义了一个ID标识&#xff0c;可以通过函数pci_find_capability和pci_find_ext_capability来探测和获取这些配置信息的位置。这些ID定义在文件include/uapi/linux/pc…

第八篇 Asciidoc 输出 All In One HTML 解决图片无法显示问题

问题:我的图片显示不出来了 小明使用 Asciidoc 来记笔记,他将笔记输出为 HTML 文件。小丽向小明借笔记。小明将 Asciidoc 笔记输出为 HTML文件,并拷贝给了小丽。 但是,小丽发现,图片都显示不出来了。 小丽:小明,你给我的笔记,图片都显示不出来啊。 小明:是我给你的…

【错题集-编程题】主持人调度(一)(排序)

牛客对应题目链接&#xff1a;主持人调度&#xff08;一&#xff09;_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 区间问题技巧&#xff1a;左端点排序或者按照右端点排序。 左端点排序后&#xff0c;仅需考虑后续区间是否能与前⼀个区间重叠即可。 二、代码 1、没看题解之…

2024 Google I/O大会:全方位解读最新AI技术和产品

引言&#xff1a; 2024年的Google I/O大会如期举行&#xff0c;作为技术圈的年度盛事之一&#xff0c;谷歌展示了其在人工智能领域的最新进展。本次大会尤其引人注目&#xff0c;因为它紧随着OpenAI昨天发布GPT-4o的脚步。让我们详细解析Google此次公布的各项新技术和产品&…

springcloud+nocos从零开始

首先是去nacos官网下载最新的包&#xff1a;Nacos 快速开始 | Nacos win下启动命令&#xff1a;startup.cmd -m standalone 这样就可以访问你的nacos 了。 添加一个配置&#xff0c;记住你的 DataId,和Group名字。 创建一个pom项目&#xff0c;引入springCloud <?xml ve…

外贸客户采集软件有哪些?

外贸客户采集软件可以帮助企业收集潜在客户的信息&#xff0c;以便进行市场分析和客户开发。以下是一些常用的外贸客户采集软件&#xff1a; 易谷歌地图数据采集大师&#xff1a;基于谷歌地图数据采集的软件&#xff0c;能够采集任意国家、地区的企业地址、电话号码、邮件地址等…

2024年代理!武汉重点实验室申报条件、奖励补贴

2024年武汉重点实验室申报条件、奖励补贴的想想内容整理如下&#xff0c;江岸区、江汉区、硚口区、汉阳区、武昌区、青山区、洪山区、蔡甸区、江夏区、黄陂区、新洲区、东西湖区、汉南区、武汉经开区、东湖高新区企业申报重点实验室有不明白的可了解&#xff1a; 武汉重点实验室…

linux系统查看服务器硬件信息

1、查看服务器型号、序列号 # dmidecode|grep "System Information" -A9 | egrep "Manufacturer|Product|Serial" 2、查看主板型号 # dmidecode |grep -A16 "System Information$" 或 dmidecode -t1 3、查看BIOS信息 # dmidecode -t bios 4、…