docx-make-pdf
v0.0.3
Published
convert docx file to html then to pdf with pdfmake
Readme
docx-make-pdf
中文
纯 JavaScript 的在后端(Node.js 环境)将 docx 文档转换为 PDF。搭配 docx-template 可以实现订单生成。类似 reamkit,更强的是不丢图片和单元格边框。 如果 docx 文档内容较为复杂或者对生成的 PDF 一致性要求比较高、且有条件安装 LibreOffice 的,还是强烈建议使用 docx-convert-pdf。
步骤原理:
- 通过 docx-preview 的 Node 修改版 docx-preview-node 先转换为 HTML
- 再通过 html-to-pdfmake(基于源码修改)转换为 pdfmake 的 docDefinition
- 然后通过 pdfmake 输出为 PDF 文件
优点:
- 不需要操作系统安装依赖,纯 JS 代码
- 支持输出 Buffer,方便后续通过 Node-SignPDF 等模块加数字签名
- 支持多页输出,支持识别 Word 分页符
- 异步模式 Promise
- TypeScript 友好
缺点:
- 不支持 Word 文件既包含纵向页面也包含横向页面
- 不支持 Word 文本框、图表和绝对定位的图片等
- 宽度(如表格)适应不是很精确,无法精确地水平居中(所以尽量不要使用带边框的表格)
- 不能使用系统自带字体,必须自己加工 vfs 字体文件
- 集成了思源宋体,所以包比较大
安装 (Installation)
npm install -S docx-make-pdf
使用 (Usage)
import docx2pdf from "docx-make-pdf"
docx2pdf({
docxFile:string, // docx file path, absolute path
docxBuffer:Buffer, // docx file content
},{
pageSize?: PageSize | undefined; // page size, default A4
pageOrientation?: "portrait" | "landscape"; // page orientation, default portrait
pageMargin?: pageMargin | undefined; // page margin, default 1.27cm (36pt)
version?: PDFVersion | undefined; // PDF version, default 1.7
watermark?: string | Watermark | undefined; // page watermark
language?: string | undefined; // page language, default zh-cn
vfs?: { [filename: string]: string }; // custom font data (load it yourself via require), note: filename here corresponds to the filename of normal/bold/italics/bolditalics in fonts
fonts?: TFontDictionary; // custom font definition, refer to build-vfs.js
defaultFont?: string; // default font name, default SourceHanSerifCN (Source Han Serif)
}):{
toFile: (filename: string) => Promise<string>; // write to file
toBuffer: () => Promise<Buffer>; // get generated PDF buffer
toStream: () => Promise<NodeJS.ReadableStream>; // custom pipe output
}字体的制作 (Font Customization)
由于字体涉及版权问题,pdfmake 没有内置字体,也不会读取计算机/服务器上已安装的字体,因此需要您自行制作已获得版权的字体数据并加载。
Because of font licensing issues, pdfmake does not include built-in fonts, nor does it read fonts installed on the computer/server. You need to prepare your own licensed font data and load it yourself.
docx-make-pdf 内置了开源免费商用的思源宋体。如果您要添加字体,必须先加工 vfs,然后定义字体名称和文件名的对应关系。
docx-make-pdf comes with the open-source, free-for-commercial-use Source Han Serif font. To add custom fonts, you must first process the vfs and then define the mapping between font names and filenames.
- 加工 vfs (Processing vfs)
生成 pdfmake 所能识别的字体源数据,原理是将 TTF 字体通过 Base64 编码加工成 vfs。建议最好用 TTF 字体,OTF 和 TTC 字体经验证未成功。Java 压缩过的字体也有问题,会出现无法识别的字符(似乎是空格)。
Generate font source data recognized by pdfmake. The principle is to encode TTF fonts into vfs via Base64. It's recommended to use TTF fonts—OTF and TTC fonts were not successful in testing. Java-compressed fonts also have issues with unrecognizable characters (seems to be spaces).
node build-vfs.js <path> [filename]
参数说明 (Parameters):
- path: 字体所在目录,必须放在一个目录中,不支持子目录 (font directory, must be in a single directory, subdirectories not supported)
- filename: 存储 vfs 数据的文件,默认是
build/vfs_fonts.js(file to store vfs data, default:build/vfs_fonts.js)
docx-make-pdf 的 package.json 中内置了脚本可以参考:node build-vfs.js ./fonts ./src/vfs_fonts.js
加载使用 (Loading & Using):
const vfs_fonts = require("./vfs_fonts.js")
docx2pdf({docxBuffer},{vfs:vfs_fonts})- 定义字体名称和文件名对应关系 (Defining Font Name & Filename Mapping)
要使用 vfs 还必须按照如下格式定义字体 (To use vfs, fonts must be defined in the following format):
fontFaceName:string {
"normal": filename:string,
"bold": filename:string,
"italics": filename:string,
"bolditalics": filename:string
}注意:必须定义 normal、bold、italics、bolditalics 四种样式,否则 pdfmake 会报错。如果字体没有这些样式,可以引用其他样式字体文件名,例如:
Note: All four styles (normal, bold, italics, bolditalics) must be defined, otherwise pdfmake will throw an error. If the font doesn't have these styles, you can reference other style font filenames, for example:
"SourceHanSerifCN": {
"normal": "SourceHanSerifCN-Regular.ttf",
"bold": "SourceHanSerifCN-Regular.ttf",
"italics": "SourceHanSerifCN-Regular.ttf",
"bolditalics": "SourceHanSerifCN-Regular.ttf"
}SourceHanSerifCN 就是字体名称,比如:"宋体"、"simsun"。
SourceHanSerifCN is the font name, e.g. "SimSun", "simsun".
SourceHanSerifCN-Regular.ttf 是字体文件名(不需要带路径),必须和第一步加工 vfs 时一致(大小写敏感)。
SourceHanSerifCN-Regular.ttf is the font filename (no path needed), which must match the name used in the vfs processing step (case-sensitive).
加载使用 (Loading & Using):
docx2pdf({docxBuffer},{fonts:{
fontFaceName:string {
"normal": filename:string,
"bold": filename:string,
"italics": filename:string,
"bolditalics": filename:string
}
}})提示:即使自定义了 vfs 和 fonts,也不会覆盖 docx2pdf 内置的 "SourceHanSerifCN" 和 pdfmake 内置的 "Roboto"(没有 Roboto 会报错)。
Tip: Even if you customize vfs and fonts, it will not override the built-in "SourceHanSerifCN" in docx2pdf and "Roboto" in pdfmake (pdfmake will error without Roboto).
English
A pure JavaScript library for converting DOCX documents to PDF in the backend (Node.js environment). Combined with docx-template, it can generate documents like invoices. Similar to reamkit, but better at preserving images and cell borders.
If the DOCX document content is complex or requires high PDF consistency, and you have the ability to install LibreOffice, it is strongly recommended to use docx-convert-pdf instead.
How it works:
- Converts DOCX to HTML via docx-preview-node, a Node.js fork of docx-preview
- Converts HTML to pdfmake's docDefinition via html-to-pdfmake (modified from source)
- Outputs PDF file via pdfmake
Pros:
- No OS-level dependencies required, pure JS code
- Supports Buffer output for easy digital signing with modules like Node-SignPDF
- Supports multi-page output and Word page breaks
- Async mode with Promises
- TypeScript friendly
Cons:
- Does not support Word documents with mixed portrait and landscape pages
- Does not support Word text boxes, charts, or absolutely positioned images
- Width adaptation (e.g., tables) is not very precise; cannot center horizontally with precision (avoid using bordered tables)
- Cannot use system fonts; must process vfs font files yourself
- Bundles Source Han Serif font, resulting in a large package size
Installation
npm install -S docx-make-pdf
Usage
import docx2pdf from "docx-make-pdf"
docx2pdf({
docxFile:string, // docx file path, absolute path
docxBuffer:Buffer, // docx file content
},{
pageSize?: PageSize | undefined; // page size, default A4
pageOrientation?: "portrait" | "landscape"; // page orientation, default portrait
pageMargin?: pageMargin | undefined; // page margin, default 1.27cm (36pt)
version?: PDFVersion | undefined; // PDF version, default 1.7
watermark?: string | Watermark | undefined; // page watermark
language?: string | undefined; // page language, default zh-cn
vfs?: { [filename: string]: string }; // custom font data (load it yourself via require), note: filename here corresponds to the filename of normal/bold/italics/bolditalics in fonts
fonts?: TFontDictionary; // custom font definition, refer to build-vfs.js
defaultFont?: string; // default font name, default SourceHanSerifCN (Source Han Serif)
}):{
toFile: (filename: string) => Promise<string>; // write to file
toBuffer: () => Promise<Buffer>; // get generated PDF buffer
toStream: () => Promise<NodeJS.ReadableStream>; // custom pipe output
}Font Customization
Due to font licensing issues, pdfmake does not include built-in fonts, nor does it read fonts installed on the computer/server. You need to prepare your own licensed font data and load it yourself.
docx-make-pdf comes with the open-source, free-for-commercial-use Source Han Serif font. To add custom fonts, you must first process the vfs and then define the mapping between font names and filenames.
- Processing vfs
Generate font source data recognized by pdfmake. The principle is to encode TTF fonts into vfs via Base64. It's recommended to use TTF fonts—OTF and TTC fonts were not successful in testing. Java-compressed fonts also have issues with unrecognizable characters (seems to be spaces).
node build-vfs.js <path> [filename]
Parameters:
- path: font directory, must be in a single directory, subdirectories not supported
- filename: file to store vfs data, default:
build/vfs_fonts.js
docx-make-pdf has a built-in script in package.json: node build-vfs.js ./fonts ./src/vfs_fonts.js
Loading & Using:
const vfs_fonts = require("./vfs_fonts.js")
docx2pdf({docxBuffer},{vfs:vfs_fonts})- Defining Font Name & Filename Mapping
To use vfs, fonts must be defined in the following format:
fontFaceName:string {
"normal": filename:string,
"bold": filename:string,
"italics": filename:string,
"bolditalics": filename:string
}Note: All four styles (normal, bold, italics, bolditalics) must be defined, otherwise pdfmake will throw an error. If the font doesn't have these styles, you can reference other style font filenames, for example:
"SourceHanSerifCN": {
"normal": "SourceHanSerifCN-Regular.ttf",
"bold": "SourceHanSerifCN-Regular.ttf",
"italics": "SourceHanSerifCN-Regular.ttf",
"bolditalics": "SourceHanSerifCN-Regular.ttf"
}SourceHanSerifCN is the font name, e.g. "SimSun", "simsun".
SourceHanSerifCN-Regular.ttf is the font filename (no path needed), which must match the name used in the vfs processing step (case-sensitive).
Loading & Using:
docx2pdf({docxBuffer},{fonts:{
fontFaceName:string {
"normal": filename:string,
"bold": filename:string,
"italics": filename:string,
"bolditalics": filename:string
}
}})Tip: Even if you customize vfs and fonts, it will not override the built-in "SourceHanSerifCN" in docx2pdf and "Roboto" in pdfmake (pdfmake will error without Roboto).
