html2pdf
npm install @akira1ce/html2pdfHTML -> layout -> image -> PDF。
主要的问题在于,分页的切割拆分。
适用于:自定义渲染出来的报告页面,可手动标记某些节点,以便于分页。
``bash`
npm install @akira1ce/html2pdfor
yarn add @akira1ce/html2pdf
`ts
/**
* PDF generation options
*/
export interface PdfOptions {
/* CSS selector for the units to be split across pages /
unitSelector: string;
/* Class name for page wrapper elements /
wrapperClassName?: string;
/* Vertical padding for each page /
py?: number;
/* Output PDF filename /
filename?: string;
/* Image quality (0-1) /
quality?: number;
/* Progress callback function /
onProgress?: (current: number, total: number) => void;
}
/**
* Convert HTML to PDF
*/
export declare const transfer2Pdf: (
ele: HTMLElement | string,
options: PdfOptions
) => Promise
`
`tsx
import { transfer2Pdf } from '@akira1ce/html2pdf';
export default function App() {
const handleDownload = async () => {
try {
await transfer2Pdf('.container', {
unitSelector: '.min-unit',
wrapperClassName: 'pdf-page',
});
} catch (error) {
console.error('PDF generation failed:', error);
}
};
return (
<>
{/ 容器 - 需要定宽 /}
重要注意事项
1. 必须标记单元节点:使用
unitSelector 标记需要分页的最小单元
2. 容器需要定宽:容器元素必须有固定宽度(建议 794px 对应 A4)
3. 单元节点不可跨页:每个单元节点会作为整体放在一页中,不会被切割
4. 避免过大的单元:单个单元节点高度不应超过一页高度
5. 容器 padding 会被保留:容器的 padding 样式会自动应用到 PDF 的每一页中$3
容器的 padding 会被自动识别并应用到生成的 PDF 中:
`tsx
内容 1
内容 2
`生成的 PDF 中,每一页都会保持 40px 的内边距。支持:
- 统一 padding:
padding: 40px
- 分别设置:padding: 30px 50px 40px 60px (top right bottom left)
- 单独设置:padding-top: 30px; padding-left: 50px;核心原理
核心在于布局的调整:
1. 收集单元节点:根据
unitSelector 收集所有需要分页的单元
2. 计算 A4 尺寸:根据容器宽度计算对应的 A4 页面高度
3. 自上而下布局:遍历所有单元,判断当前页是否能放下
4. 生成页面包装器:将放不下的节点移至下一页
5. 转换为图片:使用 dom-to-image 将每页转换为高清图片
6. 生成 PDF:使用 jsPDF 将图片添加到 PDF 中$3
`
┌─────────────────────┐
│ Page 1 │
│ ┌───────────────┐ │
│ │ padding (py) │ │
│ ├───────────────┤ │
│ │ Unit 1 │ │
│ ├───────────────┤ │
│ │ Unit 2 │ │
│ └───────────────┘ │
│ ┌───────────────┐ │
│ │ blank space │ │ <- 不足放下 Unit 3,填充空白
│ └───────────────┘ │
└─────────────────────┘┌─────────────────────┐
│ Page 2 │
│ ┌───────────────┐ │
│ │ padding (py) │ │
│ ├───────────────┤ │
│ │ Unit 3 │ │ <- 移到下一页
│ ├───────────────┤ │
│ │ Unit 4 │ │
│ └───────────────┘ │
└─────────────────────┘
`核心依赖
- dom-to-image - 将 DOM 转换为图片
- jspdf - 生成 PDF 文档
高级工具函数
库还导出了一些工具函数供高级使用:
`tsx
import { utils } from '@akira1ce/html2pdf';// 根据宽度计算 A4 高度
const height = utils.getA4Height(794);
// 获取元素的盒模型高度(包含 margin)
const boxHeight = utils.getBoxHeight(element);
// 深度克隆节点(包括 canvas 元素)
const clonedNode = utils.deepCloneNode(node, true);
``MIT