NodeJs导出PDF

(优于别人,并不高贵,真正的高贵应该是优于过去的自己。——海明威)

在这里插入图片描述

场景

根据订单参数生成账单PDF

结果

在这里插入图片描述

示例代码

/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
/* eslint-disable complexity */
const PDFDocument = require('pdfkit');
const fs = require('fs');
const dayjs = require('dayjs');
const AgencyWithdrawOrderStatus = {Completed: 'Completed',Submitted: 'Submitted',Rejected: 'Rejected',
}
const agencyName = 'Jasin';
const agencyEmail = 'pdfkit@dev.com';
const order = {"id": "FI-AWO-20230718-8657637839","accountID": {"id": "ID-AGE-20230707-6351711990","type": "AGENCY"},"transactionNo": "FIAWO202307180650601146","referenceID": "","transferWay": "Bank card","walletID": "FI-WAL-20230707-5401898911","transferID": "FI-TRF-20230718-4134849682","transactionID": "FI-TRA-20230718-2048728248","somoServiceFee": 345,"somoServiceFeeRate": 0.05,"bankTransferFee": 3000,"bankTransferFeeRate": 3000,"paypalTransferFee": 345,"paypalTransferFeeRate": 0.05,"paypalRemittanceAmount": 6555,"bankRemittanceAmount": 6900,"totalAmount": 6900,"status": "Submitted","transactionList": [{"brandName": "asdasdads","transactionID": "FI-TRA-20230710-1494352833","brandID": "ID-BRA-20230627-2309656536","campaignID": "AC-CAM-20230710-3827733853","campaignTitle": "Jack","orderID": "AC-ORD-20230710-2795223591","type": "AGENCY_CAMPAIGN_ORDER_PAYMENT","amount": 6900,"somoServiceFee": 345,"paypalTransferFee": 345,"bankTransferFee": 0}, {"brandName": "asdasdads","transactionID": "FI-TRA-20230710-5284753385","brandID": "ID-BRA-20230627-2309656536","campaignID": "AC-CAM-20230710-4072616238","campaignTitle": "Kami","orderID": "AC-ORD-20230710-7402268061","type": "AGENCY_CAMPAIGN_ORDER_PAYMENT","amount": 0,"somoServiceFee": 0,"paypalTransferFee": 0,"bankTransferFee": 0}],"transactionCount": 2,"accountBalance": 888750099,"withdrawalMethod": {"bankEnabled": true,"bankAccountName": "12213","bankAccountNumber": "22","bankName": "333","bankAddress": "444","bankSwiftCode": "555"},"reason": "","createdAt": {"$date": "2023-07-18T09:53:45.568Z"},"updatedAt": {"$date": "2023-07-18T09:53:45.568Z"},"__v": 0
};
const method = async () => {const pdfBuffer = await new Promise((resolve) => {// 实例化PDF对象const doc = new PDFDocument({ size: 'A4' });const fontSize = 14;const remittanceText = 'Remittance amount:';const remittanceTitleColor = '#8792A2';const remittanceAmountColor = '#181C1F';const remittanceAmountSize = 40;const orderStatusText = order.status;const orderStatusColor = {Submitted: '#4E515C',Completed: '#009944',Rejected: '#FF0000',}[orderStatusText];const orderStatusBackColor = {Submitted: '#f2f4f9',Completed: '#d8f7e6',Rejected: '#f0dede',}[orderStatusText];const orderStatusOffset = {Submitted: -6,Completed: -8,Rejected: 0,}[orderStatusText];const getFloatNumber = (number) => {return parseFloat(number.toString()).toFixed(2);};const getConvertAmount = (number) => {return number / 100;};const rejectedOffset = order.status === 'Rejected' ? 45 : 0;const remittanceAmount = order.withdrawalMethod.paypalEnabled? order.paypalRemittanceAmount: order.bankRemittanceAmount;const transferFee = order.withdrawalMethod.paypalEnabled? order.paypalTransferFee: order.bankTransferFee;const remittanceAmountLength = getFloatNumber(getConvertAmount(remittanceAmount),).length;const remittanceAmoutOffset =remittanceAmountLength - 4 > 0 ? remittanceAmountLength - 4 : 0;const transferAccount =(order.withdrawalMethod.paypalEnabled? order.withdrawalMethod.paypalAccountID: order.withdrawalMethod.bankAccountName) ?? ' ';const transferDetailTitleColor = '#F2F3F7';const transferDetailTitleSize = 16;const transferDetailBackgroundColor = '#171A1F';const transferDetailTitleText = 'Transfer detail:';const orderStatusX = 100;const orderStatusY = 105;const startX = 73;const transferDetailRectY = 150;const transferDetailX = 80;const transferDetailY = 168;const transferDetailWidth = 500;const transferDetailHeight = 60;const sideWidth = 500;const sideHeight = 1;const valueColor = '#272A33';const linceColor = '#F5F7F7';doc.// 使用字体font(`${__dirname}/Montserrat-Bold.ttf`).// 字体大小fontSize(fontSize).// 字体颜色fillColor(remittanceTitleColor).// 这一行的文本text(remittanceText).fontSize(remittanceAmountSize).fillColor(remittanceAmountColor).text(`$ ${getFloatNumber(getConvertAmount(remittanceAmount))}`).// 渲染块,指定x,y坐标以及宽高rect(orderStatusX + 112 + remittanceAmoutOffset * 23,orderStatusY - 8,92,34,).// 块的颜色fill(orderStatusBackColor).// 块的字体大小fontSize(fontSize).// 字体的颜色fillColor(orderStatusColor).font(`${__dirname}/Montserrat-Regular.ttf`).// 指定x,y坐标text(orderStatusText,orderStatusX +16 +112 +orderStatusOffset +remittanceAmoutOffset * 23,orderStatusY,);if (orderStatusText === AgencyWithdrawOrderStatus.Rejected) {doc.rect(startX, transferDetailRectY, 469, 30).fill('#FFE58F').// 插入图片image('withdraw.pdf.rejected.png',startX + 10,transferDetailRectY + 5,{ width: 20, height: 20 },).fontSize(12).fillColor('#000000').text(` ${order.reason}`, startX + 35, transferDetailRectY + 6.5);}doc.rect(startX,transferDetailRectY + rejectedOffset,transferDetailWidth,transferDetailHeight,).fill(transferDetailTitleColor).fontSize(transferDetailTitleSize).fillColor(transferDetailBackgroundColor).font(`${__dirname}/Montserrat-Bold.ttf`).text(transferDetailTitleText,transferDetailX,transferDetailY + rejectedOffset,{continued: false,baseline: 'top',},).font(`${__dirname}/Montserrat-Regular.ttf`).fontSize(fontSize).fillColor(remittanceTitleColor).text('Agency:',startX,transferDetailRectY + transferDetailHeight + 20 + rejectedOffset,{ lineBreak: false },).fillColor(valueColor).text(agencyName, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text(`Email:`, startX, doc.y, { lineBreak: false, lineGap: 5 }).fillColor(valueColor).text(agencyEmail, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Transaction No. :', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(order.transactionNo, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Reference ID. :', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(order.referenceID || ' ', startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Transfer way:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(order.transferWay, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Transfer account:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(transferAccount, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Transfer status:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(orderStatusText, startX + 200, doc.y, { lineGap: 5 }).fontSize(fontSize).fillColor(remittanceTitleColor).text('Created time:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(dayjs(order.createdAt.valueOf()).format('YYYY-MM-DD HH:mm:ss'),startX + 200,doc.y,{ lineGap: 5 },).fontSize(fontSize).fillColor(remittanceTitleColor).text('Update time:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(dayjs(order.updatedAt.valueOf()).format('YYYY-MM-DD HH:mm:ss'),startX + 200,doc.y,{ lineGap: 5 },).rect(startX, doc.y + 10, sideWidth, sideHeight).fill(linceColor).fontSize(fontSize).fillColor(remittanceTitleColor).text('Order total amount:', startX, doc.y + 20, { lineBreak: false }).fillColor(valueColor).text(`$ ${getFloatNumber(getConvertAmount(order.totalAmount))}`,startX + 200,doc.y,{lineGap: 5,},).fontSize(fontSize).fillColor(remittanceTitleColor).text('SOMO service fee:', startX, doc.y, {lineBreak: false,}).fillColor(remittanceTitleColor).text(`$ ${getFloatNumber(getConvertAmount(order.somoServiceFee))}`,startX + 200,doc.y,{lineGap: 5,strike: true,},).fontSize(fontSize).fillColor(remittanceTitleColor).text('Transfer fee:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(`$ ${getFloatNumber(getConvertAmount(transferFee))}`,startX + 200,doc.y,{lineGap: 5,},).fontSize(fontSize).fillColor(remittanceTitleColor).text('Remittance amount:', startX, doc.y, { lineBreak: false }).fillColor(valueColor).text(`$ ${getFloatNumber(getConvertAmount(remittanceAmount))}`,startX + 200,doc.y,{lineGap: 5,},).rect(startX, doc.y + 10, sideWidth, 60).fill('#F2F3F7').fontSize(transferDetailTitleSize).fillColor('#171A1F').font(`${__dirname}/Montserrat-Bold.ttf`).text('Associated with the order', transferDetailX, doc.y + 30, {lineBreak: false,baseline: 'top',}).text(' ', { lineGap: 10 }).font(`${__dirname}/Montserrat-Regular.ttf`);for (let i = 0; i < order.transactionList.length; i++) {const item = order.transactionList[i];const itemTransferFee = order.withdrawalMethod.paypalEnabled? item.paypalTransferFee: item.bankTransferFee;doc.text(' ', { lineGap: 10 });doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('Brand:', startX, doc.y, { paragraphGap: -20 }).fillColor(valueColor).text(item.brandName, startX + 200, doc.y, { lineGap: 8 });doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('Campaign:', startX, doc.y, { paragraphGap: -20 }).fillColor(valueColor).text(item.campaignTitle, startX + 200, doc.y, { lineGap: 8 });doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('Order ID:', startX, doc.y, { paragraphGap: -20 }).fillColor(valueColor).text(item.orderID, startX + 200, doc.y, { lineGap: 8 });doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('Oder price:', startX, doc.y, { paragraphGap: -20 }).fillColor(valueColor).text(`$ ${getFloatNumber(getConvertAmount(item.amount))}`,startX + 200,doc.y,{lineGap: 8,},);doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('SOMO service fee:', startX, doc.y, {paragraphGap: -20,}).fillColor(remittanceTitleColor).text(`$ ${getFloatNumber(getConvertAmount(item.somoServiceFee))}`,startX + 200,doc.y,{lineGap: 8,strike: true,},);doc.fontSize(fontSize).fillColor(remittanceTitleColor).text('Transfer fee:', startX, doc.y, { paragraphGap: -20 }).fillColor(valueColor).text(`$ ${getFloatNumber(getConvertAmount(itemTransferFee))}`,startX + 200,doc.y,{lineGap: 8,},);doc.rect(startX, doc.y + 20, sideWidth, sideHeight).fill(linceColor);}doc.end();const buffers = [];// 使用pdfkit的监听方法收集buffer,便于后续文件处理doc.on('data', buffers.push.bind(buffers));doc.on('end', () => {const pdfData = Buffer.concat(buffers);return resolve(pdfData);});});fs.writeFileSync(`${__dirname}/file.pdf`, pdfBuffer);
};
method();

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

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

相关文章

VS2015项目中,MFC内存中调用DLL函数(VC6生成的示例DLL)

本例主要讲一下&#xff0c;用VC6如何生成DLL&#xff0c;用工具WinHex取得DLL全部内容&#xff0c;VC2015项目加载内存中的DLL函数&#xff0c;并调用函数的示例。 本例中的示例代码下载&#xff0c;点击可以下载 一、VC6.0生成示例DLL项目 1.新建项目&#xff0c;…

Intellij IDEA SBT依赖分析插件

可分析模块和传递依赖 安装完插件后&#xff0c;由于IDEA BUG&#xff0c;会出现两个分析按钮&#xff0c;一个是gradle的&#xff0c;一般是后者是新安装的sbt。 选择需要分析的模块 只需要在project/plugins.sbt中添加代码&#xff0c;启动官方分析插件addDependencyTreeP…

安装mmcv失败

安装mmcv时报错 pip install mmcv这里只需要按照提示升级一下pip就可以了 pip install --upgrade pip然后安装成功

CS5523规格书|MIPI转EDP方案设计|替代LT8911芯片电路原理|ASL集睿致远CS替代龙讯

ASL芯片&#xff08;集睿致远&#xff09; CS5523是一款MIPI DSI输入&#xff0c;DP/e DP输出转换芯片&#xff0c;可pin to pin替代LT8911龙讯芯片。 MIPI DSI 最多支持 4 个通道&#xff0c;每个通道的最大运行速度为 1.5Gps。对于DP 1.2输出&#xff0c;它支持1.62Gbps和2.…

Linux 进程替换

一、进程替换 把一个进程替换为另外一个进程。对于进程&#xff0c;如果单纯只看复制或者单纯只看替换&#xff0c;没有太大的意义。将复制和替换结合在一起&#xff08;forkexec&#xff09;&#xff0c;就是系统去产生一个全新进程的一种方式。 将复制和替换结合在一起&…

Spring 自定义命名空间并解析 NameSpaceHandler

Spring 自定义命名空间解析器 1.主要步骤 主要有以下四步&#xff1a; 编写Schema文件自定义NameSpaceHandler 绑定命令空间自定义 BeanDefinitionParse 解析XML作为bd的配置元信息命名空间映射XML 2.代码实现 需要注意的时&#xff0c;把 spring.handlers 文件与 spring.s…

18万字应急管理局智慧矿山煤矿数字化矿山技术解决方案WORD

导读&#xff1a;原文《18万字应急管理局智慧矿山煤矿数字化矿山技术解决方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目 录 第一章 项目概述 1.1项目…

驱动 day4

通过字符设备驱动分步注册方式编写LED灯的驱动&#xff0c;应用程序使用ioctl函数编写硬件控制 mycdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> #inc…

【JAVA】数组练习

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 数组练习 1. 数组转字符串2. 数组拷贝3.…

mysql 数据备份和恢复

操作系统&#xff1a;22.04.1-Ubuntu mysql 版本&#xff1a;8.033 binlog 介绍 binlog 是mysql 二进制日志 binary log的简称&#xff0c;可以简单理解为数据的修改记录。 需要开启binlog,才会产生文件&#xff0c;mysql 8.0 默认开启,开启后可以在 /var/lib/mysql &#xff…

Vim在Mac电脑中的下载与安装方法:MacVim

本文介绍在Mac系统电脑中&#xff0c;下载、安装文本编辑器Vim软件&#xff08;MacVim软件&#xff09;的具体方法。 在Mac系统电脑中&#xff0c;原本就带有一个非图形界面的Vim&#xff1b;只要我们在终端中&#xff0c;输入如下的代码&#xff0c;就可以查看系统自带的非图形…

JetPack Compose 学习笔记(持续整理中...)

1.为什么要学&#xff1f; 1.命令式和声明式 UI大战,个人认为命令式UI自定义程度较高,能更深入到性能,内存优化方面,而申明式UI 是现在主流的设计,比如React,React Native,Flutter,Swift UI等等,现在性能也逐渐在变得更好 2.还有一个原因compose 是KMM 是完整跨平台的UI基础 3.…