JSpdf,前端下载大量表格数据pdf文件,不创建dom

数据量太大使用dom=》canvas=》image=》pdf.addimage方法弊端是canvas超出

浏览器承受像素会图片损害,只能将其切割转成小块的canvas,每一次调用html2canvas等待时间都很长累积时间更长,虽然最终可以做到抽取最小dom节点转canvas拼接数据,但是死卡

jspdf提供了不需要操作dom的方法,

Global - Documentation

使用line方法和text方法可以通过传递线坐标和文字位置在pdf页上画线和文字,组成表格

复制代码
function getStrLen(cItem, strLen) {
  let str = typeof cItem === 'string' || typeof cItem === 'number' ? cItem : 'null'
  let len = Math.ceil(str.length / strLen)
  if (len <= 1) {
    return str
  }
  str = String(str)
  let strn = ''

  for (let i = 0; i < len; i++) {
    strn = strn + str.substring(i * strLen, (i + 1) * strLen) + '\n'
  }
  return strn
}

async function downPDF(list, columns) {
  // 1in = 2.54cm = 25.4 mm = 72pt = 6pc
  let tablePdf = null
//绘制表格的参数
  let cardTop = 10, cardLeft = 7, textLeft = 9, textTop = 14, oneColumnNum = 35, oneRowNum = 7, oneCellWidth = 28, oneCellHeight = 8, oneStrLen = 5, pdfWidth = 203, pdfHeight = 290, strLen = 8
  let endPageNum = 0
//表格数据的整理
//整理格式成一个二维数组,第一层以列为单个元素,元素是整列的值组成的数组
  let testList = columns[0].children
  let propList = testList.map((item) => {
    return { prop: item.props.prop, label: item.props.label }
  })
  let dataList = []
  propList.forEach((item, index) => {
    let cArr = []
    cArr.push(item.label)
    list.forEach((cItem, cIndex) => {
      cArr.push(cItem[item.prop])
    })
    dataList.push(cArr)
  })
  console.log(dataList)

  //处理好表格数据的二维数组,配置pdf对象
  tablePdf = new jsPDF('p', 'mm', 'a4');
//解决中文乱码
  tablePdf.addFont("/fonts/SourceHanSansCN-Normal.ttf", "SourceHanSans", "normal")
  tablePdf.setFont("SourceHanSans");//1)doc中设置
  font: "SourceHanSans" // 2)style中设置
  tablePdf.setLineWidth(0.1)
  tablePdf.setFontSize(8)
  tablePdf.line(cardLeft, cardTop, pdfWidth, cardTop);
  let columnPages = Math.ceil(dataList.length / oneRowNum) + 1
  let rowPages = Math.ceil(dataList[0].length / oneColumnNum) + 1
  let currentData = []
  for (let i = 1; i < columnPages; i++) {
//横向分页
    let currentColumnData = dataList.slice((i - 1) * oneRowNum, i * oneRowNum)
//纵向分页
    for (let rowInddex = 1; rowInddex < rowPages; rowInddex++) {
      currentData = currentColumnData.map((item, index) => {
        return item.slice((rowInddex - 1) * oneColumnNum, rowInddex * oneColumnNum)
      })
      currentData.forEach((item, index) => {
        item.forEach((cItem, cIndex) => {

          cItem = getStrLen(cItem, strLen)
          //填文字,超过长度换行
          tablePdf.text(cItem, textLeft + index * oneCellWidth, textTop + cIndex * oneCellHeight, 'left')
          //画一次横线
          if (index === currentData.length - 1) {
            tablePdf.line(cardLeft, cardTop + cIndex * oneCellHeight, pdfWidth, cardTop + cIndex * oneCellHeight);
            //画最后一条横线
            if (cIndex === item.length - 1) {
              tablePdf.line(cardLeft, cardTop + (cIndex + 1) * oneCellHeight, pdfWidth, cardTop + (cIndex + 1) * oneCellHeight);
              endPageNum = item.length
              let ks = (pdfHeight - cardTop) / oneColumnNum
              for (let l = 0; l < oneRowNum + 1; l++) {
                tablePdf.line(cardLeft + l * oneCellWidth, cardTop, cardLeft + l * oneCellWidth, endPageNum * ks + cardTop);
              }
            }
          }

        })
      });
      if (rowInddex + 1 !== rowPages) {
        tablePdf.addPage();
      }
    }
    if (i + 1 !== columnPages) {
      tablePdf.addPage();
    }
  }
  tablePdf.save('dd.pdf')
}

数组datalist结构

效果

相关推荐
Byron070729 分钟前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
哆啦code梦32 分钟前
前端存储三剑客:localStorage、sessionStorage与Cookie解析
前端·前端存储
徐小夕@趣谈前端1 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
傻啦嘿哟1 小时前
Python操作PDF页面详解:删除指定页的完整方案
开发语言·python·pdf
Data_Journal1 小时前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
德育处主任Pro1 小时前
纯前端网格路径规划:PathFinding.js的使用方法
开发语言·前端·javascript
墨笔.丹青1 小时前
基于QtQuick开发界面设计出简易的HarmonyUI界面----下
开发语言·前端·javascript
董世昌411 小时前
深度解析浅拷贝与深拷贝:底层逻辑、实现方式及实战避坑
前端·javascript·vue.js
扶苏10021 小时前
vue使用event.dataTransfer实现A容器数据拖拽复制到到B容器
前端·vue.js·chrome
David凉宸1 小时前
Vue 3 项目的性能优化策略:从原理到实践
前端·vue.js·性能优化