首页 > 基础资料 博客日记

jspdf:即时生成pdf的插件,支持表单图文混排

2024-08-01 10:00:06基础资料围观176

这篇文章介绍了jspdf:即时生成pdf的插件,支持表单图文混排,分享给大家做个参考,收藏Java资料网收获更多编程知识

介绍

jspdf是即时生成pdj的插件,支持通过html代码或源数据生成。

快速开始

安装

官方给出的安装方式有三种:

个人觉得通过npm安装比较省事。

demo

1、这个链接🔗展示了插件可实现的效果:除了基础的文字表格混排外,还展示了合并单元格、自定义表格风格、页眉页脚等效果。

2、这个链接🔗提供了nodejs、ts和webpack的示例代码,另外在这个链接🔗可以查看html的示例代码。


核心代码

调用插件的核心代码如下:

const doc = new jsPDF()
autoTable(doc, { ... }) //花括号内为pdf内容和样式的代码,可以是html或json格式
doc.save('table.pdf') //保存文件。注意文件路径应包含文件名

等价于以下写法:

const doc = new jsPDF()
doc.autoTable({ ... }) 
doc.save('table.pdf')

后端写法

以下为文档给出的usage,其它框架的示例可以在这个链接🔗查看。

需要注意的是,不论你是使用上一节所述的哪一种写法,jsPDF和autoTable这两个插件都必须引入

import jsPDF from 'jspdf'
import autoTable from 'jspdf-autotable'

const doc = new jsPDF()

// It can parse html:
// <table id="my-table"><!-- ... --></table>
autoTable(doc, { html: '#my-table' })

// Or use javascript directly:
autoTable(doc, {
  head: [['Name', 'Email', 'Country']],
  body: [
    ['David', 'david@example.com', 'Sweden'],
    ['Castille', 'castille@example.com', 'Spain'],
    // ...
  ],
})

// Sometimes you might have to call the default function on the export (for example in Deno)
autoTable.default(doc, { html: '#my-table' })

doc.save('table.pdf')

HTML写法

以下同样为官方文档中的示例,需要通过本地文件或CDN的方式引入插件。

<script src="jspdf.min.js"></script>
<script src="jspdf.plugin.autotable.min.js"></script>
<script>
  var doc = new jsPDF()
  doc.autoTable({ html: '#my-table' })
  doc.save('table.pdf')
</script>

Let we go

由于没有试过用html配置pdf内容,故按下不表。本节介绍通过源数据进行设置的常用操作。

配置

插件支持对内容、样式、表单进行配置,具体写法请见文档

常用操作

文本

1、设置文本字体和字号:

引用的字体ttf文件得放在app/public/font路径下

doc.setFont('FZDBSJW'); //方正大标宋简体
doc.setFontSize(10.5); //五号

2、绘制文字

doc.text(lrSpace, y, data); 
  • lrSpace:左右外边距
  • y:上下外边距
  • data:文本数据

图像

1、绘制图像

doc.addImage(img_obj, format, x, y, img_width, img_height);
  • img_obj:node-base64-image模块返回的对象
const base64 = require('node-base64-image');
const img_obj = await base64.encode(img_url);
  • format:图片的格式,字符串类型。如"png"、"jpg"
  • x、y:图像左上角的坐标
  • img_width、img_height:图像的宽和高

表格

可以配置的option详见文档。以下为本人手写的示例代码,供学习参考:

doc.autoTable({
    styles: { // 设置表格的字体,不然表格中文也乱码
        fillColor: [ 255, 255, 255 ],
        font: 'FZDBSJW',
        textColor: [ 0, 0, 0 ],
        halign: 'left',
        fontSize: 10.5, // 五号
    },
    columnStyles: {
        0: {
            cellWidth: img_height*2 + 2, //旧版本中为columnWidth
            minCellHeight: img_height * 0.6
        },
        1: {
            cellWidth: img_height*2 + 2, //如各列的cellWidth不一致,将取最大值
            minCellHeight: img_height * 0.6
        },
    },
    headStyles: { // 设置表头样式
        fillColor: '#fff', // 背景颜色
        textColor: '#000', // 文字颜色
        lineColor: '#D3D3D3', // 线颜色
        lineWidth: 0.1, // 线宽
    },
    theme: 'grid', // 主题
    body: [{}], // 表格内容
    columns: [ // 表头
    {
        header: header1,
        dataKey: 'header1',
    },
    {
        header: header2,
        dataKey: 'header2',
    },
    ],
    startY: y, // 距离上边的距离
    margin: lrSpace, // 距离左右边的距离
    didDrawCell: (data) => {
        if (data.column.index === 0) {
            cellY = data.cell.y; //获取左上角位置
            cellHeight = data.cell.height; //获取格子高度
        }
    },
});

1、body支持列表和key-value两种写法:

 body:[
     ['David', 'david@example.com'],  
     ['Castille', 'castille@example.com']
 ]

等价于:

 body:[
     {'header1':'David', 'header2':'david@example.com'},  
     {'header1':'Castille', 'header2':'castille@example.com'}
 ]

2、使用hooks可以实现精细的自定义,详见文档

  • didParseCell:(HookData)=>{}-当插件完成对单元格内容的解析时调用。可用于替代特定单元格的内容或样式。
  • willDrawCell:(HookData)=>{}-在绘制单元格或行之前调用。可用于调用本地jspdf样式函数,如doc.setTextColor或在绘制文本之前更改文本的位置等。
  • didDrawCell:(HookData)=>{}-在将单元格添加到页面后调用。可用于绘制其他单元格内容,如带有doc.addImage的图像、带有doc.add text的其他文本或其他jspdf形状。
  • willDrawPage:(HookData)=>{}-在开始绘图之前调用。可以用来添加页眉或任何其他内容,您希望在每个页面上都有一个自动表格。
  • didDrawPage:(HookData)=>{}-在插件完成在页面上绘制所有内容后调用。可用于添加带有页码的页脚或您希望在每页上添加的任何其他内容—有一个自动表格。

通过didDrawCell方法,我们可以在表格中插入图片,效果如下:

代码接上面的例子:

var idx = 1;
doc.autoTable({
   // ... 省去前38行代码
   didDrawCell: (data) => {
        if (data.column.index === 0) {
            cellY = data.cell.y; //获取左上角位置
            cellHeight = data.cell.height; //获取格子高度
        }
        if (idx === 3 && data.column.index === 0) {
            doc.addImage(img_obj, 'png', data.cell.x+1, data.cell.y + 1, img_width, img_height);
        }
        if (idx === 4 && data.column.index === 1) {        
            doc.addImage(img_obj, 'png', data.cell.x+1, data.cell.y + 1, img_width, img_height);
            doc.addImage(img_obj, "png", data.cell.x + img_height + 1, data.cell.y + 1, img_height, img_height/2); 
        }
        idx++;
    },
});

由于data.row.index并不能表示所在行号,因此另外定义了一个自增变量。

data.column包含字段:

{
  "wrappedWidth": 82,
  "minReadableWidth": 51.68194444444444,
  "minWidth": 82,
  "width": 82,
  "dataKey": "header1",
  "raw": {
    "header": "header1",
    "dataKey": "header1"
  },
  "index": 1
}

data.row包含的字段:

{
  "height": 42,
  "raw": {},
  "index": 0,
  "section": "body",
  "cells": {
    "0": {
      "contentHeight": 42,
      "contentWidth": 3.5277777777777772,
      "wrappedWidth": 82,
      "minReadableWidth": 3.5277777777777772,
      "minWidth": 82,
      "width": 82,
      "height": 42,
      "x": 25,
      "y": 97.9325,
      "styles": {
        "font": "FZDBSJW",
        "fontStyle": "normal",
        "overflow": "linebreak",
        "fillColor": "#fff",
        "textColor": "#000",
        "halign": "left",
        "valign": "top",
        "fontSize": 10.5,
        "cellPadding": 1.7638888888888886,
        "lineColor": "#D3D3D3",
        "lineWidth": 0.1,
        "cellWidth": 82,
        "minCellHeight": 42,
        "minCellWidth": 0
      },
      "section": "body",
      "rowSpan": 1,
      "colSpan": 1,
      "text": [
        ""
      ]
    },
    "1": {
      "contentHeight": 42,
      "contentWidth": 3.5277777777777772,
      "wrappedWidth": 82,
      "minReadableWidth": 3.5277777777777772,
      "minWidth": 82,
      "width": 82,
      "height": 42,
      "x": 107,
      "y": 97.9325,
      "styles": {
        "font": "FZDBSJW",
        "fontStyle": "normal",
        "overflow": "linebreak",
        "fillColor": "#fff",
        "textColor": "#000",
        "halign": "left",
        "valign": "top",
        "fontSize": 10.5,
        "cellPadding": 1.7638888888888886,
        "lineColor": "#D3D3D3",
        "lineWidth": 0.1,
        "cellWidth": 82,
        "minCellHeight": 42,
        "minCellWidth": 0
      },
      "section": "body",
      "rowSpan": 1,
      "colSpan": 1,
      "text": [
        ""
      ]
    },
    "img_obj": {
      "contentHeight": 42,
      "contentWidth": 3.5277777777777772,
      "wrappedWidth": 82,
      "minReadableWidth": 3.5277777777777772,
      "minWidth": 82,
      "width": 82,
      "height": 42,
      "x": 25,
      "y": 97.9325,
      "styles": {
        "font": "FZDBSJW",
        "fontStyle": "normal",
        "overflow": "linebreak",
        "fillColor": "#fff",
        "textColor": "#000",
        "halign": "left",
        "valign": "top",
        "fontSize": 10.5,
        "cellPadding": 1.7638888888888886,
        "lineColor": "#D3D3D3",
        "lineWidth": 0.1,
        "cellWidth": 82,
        "minCellHeight": 42,
        "minCellWidth": 0
      },
      "section": "body",
      "rowSpan": 1,
      "colSpan": 1,
      "text": [
        ""
      ]
    }   
  },
  "spansMultiplePages": false
}


文章来源:https://blog.csdn.net/mustuo/article/details/136391285
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云