pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求

文章目录

利用pdfmake生成pdf文件

1.下载安装pdfmake第三方包

npm i pdfmake

2.封装生成pdf文件的共用配置

可以在utils文件夹下新建pdf文件夹,所有的pdf文件模板/共用配置等文件都放在该文件夹下

新建文件pdfUtils.js,该文件是一些公用配置项

c 复制代码
import pdfMake from 'pdfmake/build/pdfmake';
pdfMake.fonts={
	Msyh:{
		italics: 'https://example.com/fonts/fontFile3.ttf',
    	bold: 'https://example.com/fonts/fontFile4.ttf',
	}
	//可以设置文件的字体
}
export const PdfMake = pdfMake
export const baseDocDefinition={
//pdfmake中margin值的设置,4个值分别是[左,上,右,下]
	pageMargins:[40,70,40,40],//文档边距,不影响页眉页脚
	pageSize: 'A4', //设置纸张大小为A4
	pageOrientation: 'portrait', //portrait:纵向; langscape:横向,默认是纵向的
	//默认文本设置,这里的属性都是比较常见的就不赘述了
	defaultStyle:{
		font: 'Msyh',
		color: '#000000',
		bold: false,
		fontSize: 12,
		lineHeight: 1.2
	}
}
//pdf展示图片,不能直接展示url,需要对文件进行转换
export async function getImageUrl(url){
	const response=await fetch(url)
	const blob=await response.blob()
	return new Promise((resolve,reject)=>{
		const reader=new FileReader()
		reader.onload=()=>{
			const base64data=reader.result
			resolve(base64data)
		}
		reader.onerror=reject
		reader.readAdDataURL(blob)
	})
}

3.生成pdf文件的文件模板内容

新建getPdfDoc.js文件,该文件是具体要生成文件的配置

c 复制代码
import { PdfMake } from './pdfUtils.js'
import { baseDocDefinition, getImageUrl } from './pdfUtils.js'
//由于文件中某些数据是自动填充上去的,所以调用生成pdf的方法时要传填充的数据
export function getDocPDF=async(data){
	const docDefinition={
		...baseDocDefinition,
		//独有配置,这里可以参考文档最后
		content:[
			//独有的配置
			...
		]
	}
	PdfMake.createPDF(docDefinition).open()//生成pdf文件并打开,可以进行预览/导出
}

4.调用方法生成pdf

在需要的地方进行调用

例如:

c 复制代码
<template>
...
<el-button @click='exportDoc'>导出PDF文件</el-button>
...
</template>
import { getDocPDF } from '@/utils/getPdfDoc.js'
<script>
export default {
	data(){
		return {
			form:{}
		}
	},
	methods:{
		async exportDoc(){
			await getDocPDF(this.form)
		}
	}
}
</script>

pdfmake的文档没有中文版的,这里我列举一些我用过的也是比较常用的配置

c 复制代码
export function getDocPDF=async(data){
	const docDefinition={
		...baseDocDefinition,
		//页眉
		header: {
      		absolutePosition: { x: 40, y: 10 },
      		stack: [
        		{ text: `${data.fullName}`, fontSize: 10, absolutePosition: { x: 0, y: 13 }, alignment: 'center' },
        		{
          			canvas: [{
            			type: 'line',
            			x1: 0,
            			y1: 30,
            			x2: 515,
            			y2: 30,
            			lineWidth: 1,
            			absolutePosition: { x: 0, y: 10 }
          			}]
        		},// 分割线
      		],
    	},
    	//页脚
    	footer: function (currentPage, pageCount) {
      		return [
        		{
          			canvas: [
            			{
              				type: 'line',
              				x1: 40, y1: 0,
              				x2: 555, y2: 0,
              				lineWidth: 1
            			}
          			]
        		},
        		{
          			text: `${data.fullName}\n` + currentPage,
          			alignment: 'center',
          			fontSize: 10,
          			margin: [0, 10]
        		}
      		];
    	},
		content:[
			//独有的配置
			...,
			//文本段落
			{
				text:'***',
				fontSize:16,//该段text的字体大小
				bold:true,//该段字体加粗
				lendingIndent: 25//首行缩进
			},
			//表格
			{
				layout:{
					paddingTop: () => 5,
          			paddingBottom: () => 5,
          			paddingLeft: () => 5,
          			paddingRight: () => 5
				},
				table: {
          			widths: ['10%', '22%', '20%', '30%', '20%'],
          			body: [
            			[
            			//第一行的数据,即表格的表头
              				{ text: '序号', alignment: 'center' },
              				{ text: '姓名', alignment: 'center' },
              				{ text: '手机号', alignment: 'center' },
              				{ text: '性别', alignment: 'center' },
            			],
            			//后面的数据行,如果不是静态的数据,传入的数据展示我们可能还需要进行一下转换,转换成这里展示需要的数据格式
            			[
            				{ text: '1', alignment: 'center' },
              				{ text: '张三', alignment: 'center' },
              				{ text: '18888888888', alignment: 'center' },
              				{ text: '男', alignment: 'center' },
            			],
          			]
        		}
			},
			//左右布局
			{
				alignment: 'justify',
        		margin: [0, 20, 0, 5],
        		columns: [
          			{
          			//text可以直接是字符串,也可以是字符串数组
            			text: [
							'签字日期:','\u00A0\u00A0\u00A0\u00A0','年','\u00A0\u00A0\u00A0\u00A0','月','\u00A0\u00A0\u00A0\u00A0','日'//这里的\u00A0是导出来展示是空格
						],
            			fontSize: 12
          			},
          			{
            			text: '签字日期:','\u00A0\u00A0\u00A0\u00A0','年','\u00A0\u00A0\u00A0\u00A0','月','\u00A0\u00A0\u00A0\u00A0','日',
            			fontSize: 12
          			}
        		]
			},
			//如果需要换页,即下面的内容为新起一页的内容,可以通过给文本块加上pageBreak属性
			{
				text:' ',
				pageBreak:'after',//表示该文本块后换页
			},
			//如果需要展示像图片,或者文本块较多,要放在stack中,图片不能直接展示url,要进行格式转换
			stack:[
				{
					image: await getImageUrl(data.url)
					width: 200,
				}
			]
		]
	}
	PdfMake.createPDF(docDefinition).open()//生成pdf文件并打开,可以进行预览/导出
}

页眉效果

页脚效果

相关推荐
测试界的酸菜鱼5 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
web行路人13 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00115 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
晨曦_子画15 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend23 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
子非鱼92133 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂35 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
残月只会敲键盘1 小时前
php代码审计--常见函数整理
开发语言·php
xianwu5431 小时前
反向代理模块
linux·开发语言·网络·git