pdf-composer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.esm.js +129 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +130 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# pdf-composer
|
|
2
|
+
|
|
3
|
+
将组合多种内容转换为 PDF 文件的 JavaScript/TypeScript 库,支持浏览器环境。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 **简单易用** - 一行代码将 Markdown 转换为 PDF
|
|
8
|
+
- 📦 **TypeScript 支持** - 完整的类型定义
|
|
9
|
+
- 🎨 **样式丰富** - 内置美观的 Markdown 样式
|
|
10
|
+
- 📄 **多页支持** - 自动分页处理
|
|
11
|
+
- 🖼️ **Mermaid 支持** - 可选集成 Mermaid 图表
|
|
12
|
+
- ⚙️ **高度可配置** - 支持自定义页面大小、方向、边距等
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install pdf-composer
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
或使用 yarn:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
yarn add pdf-composer
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 快速开始
|
|
27
|
+
|
|
28
|
+
### 基础用法
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
import { generationPDF } from 'pdf-composer';
|
|
32
|
+
|
|
33
|
+
const markdown = `
|
|
34
|
+
# 标题
|
|
35
|
+
|
|
36
|
+
这是一段 **Markdown** 文本。
|
|
37
|
+
|
|
38
|
+
## 列表示例
|
|
39
|
+
|
|
40
|
+
- 项目 1
|
|
41
|
+
- 项目 2
|
|
42
|
+
- 项目 3
|
|
43
|
+
|
|
44
|
+
## 代码示例
|
|
45
|
+
|
|
46
|
+
\`\`\`javascript
|
|
47
|
+
function hello() {
|
|
48
|
+
console.log('Hello, World!');
|
|
49
|
+
}
|
|
50
|
+
\`\`\`
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
// 生成 PDF
|
|
54
|
+
const result = await generationPDF(markdown, undefined, 'example.pdf');
|
|
55
|
+
|
|
56
|
+
if (result.success) {
|
|
57
|
+
console.log(`PDF 生成成功,共 ${result.pageCount} 页`);
|
|
58
|
+
} else {
|
|
59
|
+
console.error('PDF 生成失败:', result.error);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 高级用法(使用选项对象)
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import { generationPDFWithOptions } from 'pdf-composer';
|
|
67
|
+
|
|
68
|
+
const result = await generationPDFWithOptions({
|
|
69
|
+
markdownText: markdown,
|
|
70
|
+
fileName: 'output.pdf',
|
|
71
|
+
pageFormat: 'a4', // 页面大小: 'a3' | 'a4' | 'letter' | 'legal'
|
|
72
|
+
orientation: 'p', // 方向: 'p'(纵向) | 'l'(横向)
|
|
73
|
+
padding: 10, // 页边距 (mm)
|
|
74
|
+
scale: 2, // 渲染缩放比例
|
|
75
|
+
containerWidth: 1200, // 容器宽度 (px)
|
|
76
|
+
containerPadding: 40 // 容器内边距 (px)
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 结合 Mermaid 使用
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<!DOCTYPE html>
|
|
84
|
+
<html>
|
|
85
|
+
<head>
|
|
86
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
|
87
|
+
<script type="module">
|
|
88
|
+
import { generationPDF } from 'pdf-composer';
|
|
89
|
+
|
|
90
|
+
// 初始化 Mermaid
|
|
91
|
+
mermaid.initialize({ startOnLoad: true });
|
|
92
|
+
|
|
93
|
+
async function exportPdf() {
|
|
94
|
+
const markdown = `
|
|
95
|
+
# 流程图示例
|
|
96
|
+
|
|
97
|
+
下面是一个流程图:
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
// mermaid-preview 是包含 Mermaid SVG 的 DOM 元素 ID
|
|
101
|
+
const result = await generationPDF(markdown, 'mermaid-preview', 'diagram.pdf');
|
|
102
|
+
}
|
|
103
|
+
</script>
|
|
104
|
+
</head>
|
|
105
|
+
<body>
|
|
106
|
+
<div id="mermaid-preview">
|
|
107
|
+
<pre class="mermaid">
|
|
108
|
+
graph LR
|
|
109
|
+
A[开始] --> B{判断}
|
|
110
|
+
B -->|是| C[操作A]
|
|
111
|
+
B -->|否| D[操作B]
|
|
112
|
+
</pre>
|
|
113
|
+
</div>
|
|
114
|
+
<button onclick="exportPdf()">导出 PDF</button>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## API 文档
|
|
120
|
+
|
|
121
|
+
### `generationPDF(markdownText, mermaidDomId?, fileName?)`
|
|
122
|
+
|
|
123
|
+
基础 PDF 生成函数。
|
|
124
|
+
|
|
125
|
+
**参数:**
|
|
126
|
+
|
|
127
|
+
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|
|
128
|
+
|------|------|------|--------|------|
|
|
129
|
+
| `markdownText` | `string` | 是 | - | Markdown 文本内容 |
|
|
130
|
+
| `mermaidDomId` | `string` | 否 | `undefined` | 包含 Mermaid SVG 的 DOM 元素 ID |
|
|
131
|
+
| `fileName` | `string` | 否 | `'output.pdf'` | 输出的 PDF 文件名 |
|
|
132
|
+
|
|
133
|
+
**返回值:**
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface GenerationPdfResult {
|
|
137
|
+
success: boolean; // 是否成功
|
|
138
|
+
pageCount?: number; // 生成的页数
|
|
139
|
+
error?: Error; // 错误信息(失败时)
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### `generationPDFWithOptions(options)`
|
|
146
|
+
|
|
147
|
+
高级 PDF 生成函数,支持更多配置选项。
|
|
148
|
+
|
|
149
|
+
**参数:**
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
interface GenerationPdfOptions {
|
|
153
|
+
markdownText: string; // Markdown 文本内容(必填)
|
|
154
|
+
mermaidDomId?: string; // Mermaid DOM 元素 ID
|
|
155
|
+
fileName?: string; // 输出文件名,默认 'output.pdf'
|
|
156
|
+
containerWidth?: number; // 容器宽度,默认 1200
|
|
157
|
+
containerPadding?: number; // 容器内边距,默认 40
|
|
158
|
+
scale?: number; // 渲染缩放比例,默认 2
|
|
159
|
+
pageFormat?: 'a3' | 'a4' | 'letter' | 'legal'; // 页面大小,默认 'a4'
|
|
160
|
+
orientation?: 'p' | 'l'; // 页面方向,默认 'p'(纵向)
|
|
161
|
+
padding?: number; // 页边距,默认 10
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**返回值:** 同 `generationPDF`
|
|
166
|
+
|
|
167
|
+
## 依赖说明
|
|
168
|
+
|
|
169
|
+
本库依赖以下 npm 包:
|
|
170
|
+
|
|
171
|
+
- [marked](https://www.npmjs.com/package/marked) - Markdown 解析器
|
|
172
|
+
- [html2canvas](https://www.npmjs.com/package/html2canvas) - HTML 转 Canvas
|
|
173
|
+
- [jspdf](https://www.npmjs.com/package/jspdf) - PDF 生成
|
|
174
|
+
|
|
175
|
+
**注意:** Mermaid 不包含在本库中,如需使用 Mermaid 图表,请通过 CDN 加载:
|
|
176
|
+
|
|
177
|
+
```html
|
|
178
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 浏览器兼容性
|
|
182
|
+
|
|
183
|
+
本库仅支持浏览器环境,不支持 Node.js。
|
|
184
|
+
|
|
185
|
+
支持的浏览器:
|
|
186
|
+
- Chrome >= 60
|
|
187
|
+
- Firefox >= 55
|
|
188
|
+
- Safari >= 11
|
|
189
|
+
- Edge >= 79
|
|
190
|
+
|
|
191
|
+
## 开发
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 安装依赖
|
|
195
|
+
npm install
|
|
196
|
+
|
|
197
|
+
# 构建
|
|
198
|
+
npm run build
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 许可证
|
|
202
|
+
|
|
203
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface GenerationPdfOptions {
|
|
2
|
+
markdownText: string;
|
|
3
|
+
mermaidDomId?: string;
|
|
4
|
+
fileName?: string;
|
|
5
|
+
containerWidth?: number;
|
|
6
|
+
containerPadding?: number;
|
|
7
|
+
scale?: number;
|
|
8
|
+
pageFormat?: 'a3' | 'a4' | 'letter' | 'legal';
|
|
9
|
+
orientation?: 'p' | 'l';
|
|
10
|
+
padding?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface GenerationPdfResult {
|
|
13
|
+
success: boolean;
|
|
14
|
+
pageCount?: number;
|
|
15
|
+
error?: Error;
|
|
16
|
+
}
|
|
17
|
+
export declare function generationPDF(markdownText: string, mermaidDomId?: string, fileName?: string): Promise<GenerationPdfResult>;
|
|
18
|
+
export declare function generationPDFWithOptions(options: GenerationPdfOptions): Promise<GenerationPdfResult>;
|
|
19
|
+
export default generationPDF;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { parse } from 'marked';
|
|
2
|
+
import html2canvas from 'html2canvas';
|
|
3
|
+
import { jsPDF } from 'jspdf';
|
|
4
|
+
const DEFAULT_STYLES = `
|
|
5
|
+
h1 { font-size: 36px; margin-bottom: 20px; font-weight: bold; color: #2c3e50; }
|
|
6
|
+
h2 { font-size: 28px; margin: 25px 0 12px; font-weight: bold; color: #34495e; }
|
|
7
|
+
h3 { font-size: 22px; margin: 20px 0 10px; font-weight: bold; color: #34495e; }
|
|
8
|
+
h4 { font-size: 18px; margin: 18px 0 8px; font-weight: bold; color: #34495e; }
|
|
9
|
+
h5 { font-size: 16px; margin: 16px 0 6px; font-weight: bold; color: #34495e; }
|
|
10
|
+
h6 { font-size: 14px; margin: 14px 0 4px; font-weight: bold; color: #34495e; }
|
|
11
|
+
p { margin: 12px 0; color: #2c3e50; }
|
|
12
|
+
ul, ol { padding-left: 30px; margin: 12px 0; }
|
|
13
|
+
li { margin: 8px 0; }
|
|
14
|
+
code { background: #f4f4f4; padding: 3px 8px; border-radius: 4px; font-family: monospace; font-size: 14px; }
|
|
15
|
+
pre { background: #2d2d2d; color: #ccc; padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 14px; }
|
|
16
|
+
pre code { background: none; padding: 0; color: inherit; }
|
|
17
|
+
blockquote { border-left: 4px solid #667eea; padding-left: 16px; margin: 16px 0; color: #7f8c8d; font-style: italic; }
|
|
18
|
+
table { width: 100%; border-collapse: collapse; margin: 16px 0; }
|
|
19
|
+
th, td { border: 1px solid #ddd; padding: 10px 14px; text-align: left; }
|
|
20
|
+
th { background: #f8f9fa; font-weight: bold; }
|
|
21
|
+
a { color: #667eea; text-decoration: none; }
|
|
22
|
+
hr { border: none; border-top: 1px solid #eee; margin: 20px 0; }
|
|
23
|
+
img { max-width: 100%; height: auto; }
|
|
24
|
+
`;
|
|
25
|
+
const PAGE_SIZES = {
|
|
26
|
+
a3: { width: 297, height: 420 },
|
|
27
|
+
a4: { width: 210, height: 297 },
|
|
28
|
+
letter: { width: 215.9, height: 279.4 },
|
|
29
|
+
legal: { width: 215.9, height: 355.6 }
|
|
30
|
+
};
|
|
31
|
+
export async function generationPDF(markdownText, mermaidDomId, fileName = 'output.pdf') {
|
|
32
|
+
return generationPDFWithOptions({
|
|
33
|
+
markdownText,
|
|
34
|
+
mermaidDomId,
|
|
35
|
+
fileName
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function generationPDFWithOptions(options) {
|
|
39
|
+
const { markdownText, mermaidDomId, fileName = 'output.pdf', containerWidth = 1200, containerPadding = 40, scale = 2, pageFormat = 'a4', orientation = 'p', padding = 10 } = options;
|
|
40
|
+
try {
|
|
41
|
+
const markdownHtml = parse(markdownText);
|
|
42
|
+
const exportContainer = document.createElement('div');
|
|
43
|
+
exportContainer.id = 'pdf-export-container';
|
|
44
|
+
exportContainer.style.cssText = `
|
|
45
|
+
position: absolute;
|
|
46
|
+
left: -2000px;
|
|
47
|
+
top: -2000px;
|
|
48
|
+
width: ${containerWidth}px;
|
|
49
|
+
padding: ${containerPadding}px;
|
|
50
|
+
background: white;
|
|
51
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Microsoft YaHei, sans-serif;
|
|
52
|
+
font-size: 18px;
|
|
53
|
+
line-height: 1.8;
|
|
54
|
+
`;
|
|
55
|
+
exportContainer.innerHTML = `
|
|
56
|
+
<style>${DEFAULT_STYLES}</style>
|
|
57
|
+
<div style="max-width: ${containerWidth - containerPadding * 2}px; margin: 0 auto;">
|
|
58
|
+
${markdownHtml}
|
|
59
|
+
</div>
|
|
60
|
+
`;
|
|
61
|
+
if (mermaidDomId) {
|
|
62
|
+
const mermaidEl = document.getElementById(mermaidDomId);
|
|
63
|
+
if (mermaidEl) {
|
|
64
|
+
const svg = mermaidEl.querySelector('svg');
|
|
65
|
+
if (svg) {
|
|
66
|
+
const svgWrapper = document.createElement('div');
|
|
67
|
+
svgWrapper.style.cssText = 'margin: 25px 0; text-align: center;';
|
|
68
|
+
const svgClone = svg.cloneNode(true);
|
|
69
|
+
svgClone.style.cssText = 'max-width: 1000px; width: 100%; height: auto;';
|
|
70
|
+
svgWrapper.appendChild(svgClone);
|
|
71
|
+
exportContainer.appendChild(svgWrapper);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
document.body.appendChild(exportContainer);
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
77
|
+
const containerHeight = exportContainer.scrollHeight;
|
|
78
|
+
const pageSize = PAGE_SIZES[pageFormat] || PAGE_SIZES.a4;
|
|
79
|
+
const pageWidth = orientation === 'l' ? pageSize.height : pageSize.width;
|
|
80
|
+
const pageHeight = orientation === 'l' ? pageSize.width : pageSize.height;
|
|
81
|
+
const pageContentHeight = pageHeight - padding * 2;
|
|
82
|
+
const pdf = new jsPDF({
|
|
83
|
+
orientation: orientation,
|
|
84
|
+
unit: 'mm',
|
|
85
|
+
format: pageFormat
|
|
86
|
+
});
|
|
87
|
+
const canvas = await html2canvas(exportContainer, {
|
|
88
|
+
scale: scale,
|
|
89
|
+
useCORS: true,
|
|
90
|
+
logging: false,
|
|
91
|
+
width: containerWidth,
|
|
92
|
+
height: containerHeight,
|
|
93
|
+
windowHeight: containerHeight + 100,
|
|
94
|
+
scrollY: 0
|
|
95
|
+
});
|
|
96
|
+
const imgWidth = pageWidth - padding * 2;
|
|
97
|
+
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
98
|
+
const pageCount = Math.ceil(imgHeight / pageContentHeight);
|
|
99
|
+
for (let i = 0; i < pageCount; i++) {
|
|
100
|
+
if (i > 0) {
|
|
101
|
+
pdf.addPage();
|
|
102
|
+
}
|
|
103
|
+
const startY = Math.floor(i * pageContentHeight * canvas.height / imgHeight);
|
|
104
|
+
const endY = Math.min(startY + Math.floor(pageContentHeight * canvas.height / imgHeight), canvas.height);
|
|
105
|
+
const pageCanvasHeight = endY - startY;
|
|
106
|
+
const pageCanvas = document.createElement('canvas');
|
|
107
|
+
pageCanvas.width = canvas.width;
|
|
108
|
+
pageCanvas.height = pageCanvasHeight;
|
|
109
|
+
const ctx = pageCanvas.getContext('2d');
|
|
110
|
+
if (ctx) {
|
|
111
|
+
ctx.fillStyle = '#ffffff';
|
|
112
|
+
ctx.fillRect(0, 0, pageCanvas.width, pageCanvas.height);
|
|
113
|
+
ctx.drawImage(canvas, 0, startY, canvas.width, pageCanvasHeight, 0, 0, pageCanvas.width, pageCanvasHeight);
|
|
114
|
+
}
|
|
115
|
+
const pageImgData = pageCanvas.toDataURL('image/jpeg', 0.95);
|
|
116
|
+
const pageImgHeight = (pageCanvasHeight / canvas.height) * imgHeight;
|
|
117
|
+
pdf.addImage(pageImgData, 'JPEG', padding, padding, imgWidth, pageImgHeight);
|
|
118
|
+
}
|
|
119
|
+
pdf.save(fileName);
|
|
120
|
+
document.body.removeChild(exportContainer);
|
|
121
|
+
return { success: true, pageCount: pageCount };
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('生成PDF失败:', error);
|
|
125
|
+
return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export default generationPDF;
|
|
129
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generationPDF = generationPDF;
|
|
7
|
+
exports.generationPDFWithOptions = generationPDFWithOptions;
|
|
8
|
+
const marked_1 = require("marked");
|
|
9
|
+
const html2canvas_1 = __importDefault(require("html2canvas"));
|
|
10
|
+
const jspdf_1 = require("jspdf");
|
|
11
|
+
const DEFAULT_STYLES = `
|
|
12
|
+
h1 { font-size: 36px; margin-bottom: 20px; font-weight: bold; color: #2c3e50; }
|
|
13
|
+
h2 { font-size: 28px; margin: 25px 0 12px; font-weight: bold; color: #34495e; }
|
|
14
|
+
h3 { font-size: 22px; margin: 20px 0 10px; font-weight: bold; color: #34495e; }
|
|
15
|
+
h4 { font-size: 18px; margin: 18px 0 8px; font-weight: bold; color: #34495e; }
|
|
16
|
+
h5 { font-size: 16px; margin: 16px 0 6px; font-weight: bold; color: #34495e; }
|
|
17
|
+
h6 { font-size: 14px; margin: 14px 0 4px; font-weight: bold; color: #34495e; }
|
|
18
|
+
p { margin: 12px 0; color: #2c3e50; }
|
|
19
|
+
ul, ol { padding-left: 30px; margin: 12px 0; }
|
|
20
|
+
li { margin: 8px 0; }
|
|
21
|
+
code { background: #f4f4f4; padding: 3px 8px; border-radius: 4px; font-family: monospace; font-size: 14px; }
|
|
22
|
+
pre { background: #2d2d2d; color: #ccc; padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 14px; }
|
|
23
|
+
pre code { background: none; padding: 0; color: inherit; }
|
|
24
|
+
blockquote { border-left: 4px solid #667eea; padding-left: 16px; margin: 16px 0; color: #7f8c8d; font-style: italic; }
|
|
25
|
+
table { width: 100%; border-collapse: collapse; margin: 16px 0; }
|
|
26
|
+
th, td { border: 1px solid #ddd; padding: 10px 14px; text-align: left; }
|
|
27
|
+
th { background: #f8f9fa; font-weight: bold; }
|
|
28
|
+
a { color: #667eea; text-decoration: none; }
|
|
29
|
+
hr { border: none; border-top: 1px solid #eee; margin: 20px 0; }
|
|
30
|
+
img { max-width: 100%; height: auto; }
|
|
31
|
+
`;
|
|
32
|
+
const PAGE_SIZES = {
|
|
33
|
+
a3: { width: 297, height: 420 },
|
|
34
|
+
a4: { width: 210, height: 297 },
|
|
35
|
+
letter: { width: 215.9, height: 279.4 },
|
|
36
|
+
legal: { width: 215.9, height: 355.6 }
|
|
37
|
+
};
|
|
38
|
+
async function generationPDF(markdownText, mermaidDomId, fileName = 'output.pdf') {
|
|
39
|
+
return generationPDFWithOptions({
|
|
40
|
+
markdownText,
|
|
41
|
+
mermaidDomId,
|
|
42
|
+
fileName
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function generationPDFWithOptions(options) {
|
|
46
|
+
const { markdownText, mermaidDomId, fileName = 'output.pdf', containerWidth = 1200, containerPadding = 40, scale = 2, pageFormat = 'a4', orientation = 'p', padding = 10 } = options;
|
|
47
|
+
try {
|
|
48
|
+
const markdownHtml = (0, marked_1.parse)(markdownText);
|
|
49
|
+
const exportContainer = document.createElement('div');
|
|
50
|
+
exportContainer.id = 'pdf-export-container';
|
|
51
|
+
exportContainer.style.cssText = `
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: -2000px;
|
|
54
|
+
top: -2000px;
|
|
55
|
+
width: ${containerWidth}px;
|
|
56
|
+
padding: ${containerPadding}px;
|
|
57
|
+
background: white;
|
|
58
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Microsoft YaHei, sans-serif;
|
|
59
|
+
font-size: 18px;
|
|
60
|
+
line-height: 1.8;
|
|
61
|
+
`;
|
|
62
|
+
exportContainer.innerHTML = `
|
|
63
|
+
<style>${DEFAULT_STYLES}</style>
|
|
64
|
+
<div style="max-width: ${containerWidth - containerPadding * 2}px; margin: 0 auto;">
|
|
65
|
+
${markdownHtml}
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
68
|
+
if (mermaidDomId) {
|
|
69
|
+
const mermaidEl = document.getElementById(mermaidDomId);
|
|
70
|
+
if (mermaidEl) {
|
|
71
|
+
const svg = mermaidEl.querySelector('svg');
|
|
72
|
+
if (svg) {
|
|
73
|
+
const svgWrapper = document.createElement('div');
|
|
74
|
+
svgWrapper.style.cssText = 'margin: 25px 0; text-align: center;';
|
|
75
|
+
const svgClone = svg.cloneNode(true);
|
|
76
|
+
svgClone.style.cssText = 'max-width: 1000px; width: 100%; height: auto;';
|
|
77
|
+
svgWrapper.appendChild(svgClone);
|
|
78
|
+
exportContainer.appendChild(svgWrapper);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
document.body.appendChild(exportContainer);
|
|
83
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
84
|
+
const containerHeight = exportContainer.scrollHeight;
|
|
85
|
+
const pageSize = PAGE_SIZES[pageFormat] || PAGE_SIZES.a4;
|
|
86
|
+
const pageWidth = orientation === 'l' ? pageSize.height : pageSize.width;
|
|
87
|
+
const pageHeight = orientation === 'l' ? pageSize.width : pageSize.height;
|
|
88
|
+
const pageContentHeight = pageHeight - padding * 2;
|
|
89
|
+
const pdf = new jspdf_1.jsPDF({
|
|
90
|
+
orientation: orientation,
|
|
91
|
+
unit: 'mm',
|
|
92
|
+
format: pageFormat
|
|
93
|
+
});
|
|
94
|
+
const canvas = await (0, html2canvas_1.default)(exportContainer, {
|
|
95
|
+
scale: scale,
|
|
96
|
+
useCORS: true,
|
|
97
|
+
logging: false,
|
|
98
|
+
width: containerWidth,
|
|
99
|
+
height: containerHeight,
|
|
100
|
+
windowHeight: containerHeight + 100,
|
|
101
|
+
scrollY: 0
|
|
102
|
+
});
|
|
103
|
+
const imgWidth = pageWidth - padding * 2;
|
|
104
|
+
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
105
|
+
const pageCount = Math.ceil(imgHeight / pageContentHeight);
|
|
106
|
+
for (let i = 0; i < pageCount; i++) {
|
|
107
|
+
if (i > 0) {
|
|
108
|
+
pdf.addPage();
|
|
109
|
+
}
|
|
110
|
+
const startY = Math.floor(i * pageContentHeight * canvas.height / imgHeight);
|
|
111
|
+
const endY = Math.min(startY + Math.floor(pageContentHeight * canvas.height / imgHeight), canvas.height);
|
|
112
|
+
const pageCanvasHeight = endY - startY;
|
|
113
|
+
const pageCanvas = document.createElement('canvas');
|
|
114
|
+
pageCanvas.width = canvas.width;
|
|
115
|
+
pageCanvas.height = pageCanvasHeight;
|
|
116
|
+
const ctx = pageCanvas.getContext('2d');
|
|
117
|
+
if (ctx) {
|
|
118
|
+
ctx.fillStyle = '#ffffff';
|
|
119
|
+
ctx.fillRect(0, 0, pageCanvas.width, pageCanvas.height);
|
|
120
|
+
ctx.drawImage(canvas, 0, startY, canvas.width, pageCanvasHeight, 0, 0, pageCanvas.width, pageCanvasHeight);
|
|
121
|
+
}
|
|
122
|
+
const pageImgData = pageCanvas.toDataURL('image/jpeg', 0.95);
|
|
123
|
+
const pageImgHeight = (pageCanvasHeight / canvas.height) * imgHeight;
|
|
124
|
+
pdf.addImage(pageImgData, 'JPEG', padding, padding, imgWidth, pageImgHeight);
|
|
125
|
+
}
|
|
126
|
+
pdf.save(fileName);
|
|
127
|
+
document.body.removeChild(exportContainer);
|
|
128
|
+
return { success: true, pageCount: pageCount };
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.error('生成PDF失败:', error);
|
|
132
|
+
return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.default = generationPDF;
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pdfComposer=f()}})(function(){
|
|
2
|
+
var marked = window.marked;
|
|
3
|
+
var html2canvas = window.html2canvas;
|
|
4
|
+
var jsPDF = window.jspdf.jsPDF;
|
|
5
|
+
const DEFAULT_STYLES = `
|
|
6
|
+
h1 { font-size: 36px; margin-bottom: 20px; font-weight: bold; color: #2c3e50; }
|
|
7
|
+
h2 { font-size: 28px; margin: 25px 0 12px; font-weight: bold; color: #34495e; }
|
|
8
|
+
h3 { font-size: 22px; margin: 20px 0 10px; font-weight: bold; color: #34495e; }
|
|
9
|
+
h4 { font-size: 18px; margin: 18px 0 8px; font-weight: bold; color: #34495e; }
|
|
10
|
+
h5 { font-size: 16px; margin: 16px 0 6px; font-weight: bold; color: #34495e; }
|
|
11
|
+
h6 { font-size: 14px; margin: 14px 0 4px; font-weight: bold; color: #34495e; }
|
|
12
|
+
p { margin: 12px 0; color: #2c3e50; }
|
|
13
|
+
ul, ol { padding-left: 30px; margin: 12px 0; }
|
|
14
|
+
li { margin: 8px 0; }
|
|
15
|
+
code { background: #f4f4f4; padding: 3px 8px; border-radius: 4px; font-family: monospace; font-size: 14px; }
|
|
16
|
+
pre { background: #2d2d2d; color: #ccc; padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 14px; }
|
|
17
|
+
pre code { background: none; padding: 0; color: inherit; }
|
|
18
|
+
blockquote { border-left: 4px solid #667eea; padding-left: 16px; margin: 16px 0; color: #7f8c8d; font-style: italic; }
|
|
19
|
+
table { width: 100%; border-collapse: collapse; margin: 16px 0; }
|
|
20
|
+
th, td { border: 1px solid #ddd; padding: 10px 14px; text-align: left; }
|
|
21
|
+
th { background: #f8f9fa; font-weight: bold; }
|
|
22
|
+
a { color: #667eea; text-decoration: none; }
|
|
23
|
+
hr { border: none; border-top: 1px solid #eee; margin: 20px 0; }
|
|
24
|
+
img { max-width: 100%; height: auto; }
|
|
25
|
+
`;
|
|
26
|
+
const PAGE_SIZES = {
|
|
27
|
+
a3: { width: 297, height: 420 },
|
|
28
|
+
a4: { width: 210, height: 297 },
|
|
29
|
+
letter: { width: 215.9, height: 279.4 },
|
|
30
|
+
legal: { width: 215.9, height: 355.6 }
|
|
31
|
+
};
|
|
32
|
+
async function generationPDF(markdownText, mermaidDomId, fileName = 'output.pdf') {
|
|
33
|
+
return generationPDFWithOptions({
|
|
34
|
+
markdownText,
|
|
35
|
+
mermaidDomId,
|
|
36
|
+
fileName
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function generationPDFWithOptions(options) {
|
|
40
|
+
const { markdownText, mermaidDomId, fileName = 'output.pdf', containerWidth = 1200, containerPadding = 40, scale = 2, pageFormat = 'a4', orientation = 'p', padding = 10 } = options;
|
|
41
|
+
try {
|
|
42
|
+
const markdownHtml = marked.parse(markdownText);
|
|
43
|
+
const exportContainer = document.createElement('div');
|
|
44
|
+
exportContainer.id = 'pdf-export-container';
|
|
45
|
+
exportContainer.style.cssText = `
|
|
46
|
+
position: absolute;
|
|
47
|
+
left: -2000px;
|
|
48
|
+
top: -2000px;
|
|
49
|
+
width: ${containerWidth}px;
|
|
50
|
+
padding: ${containerPadding}px;
|
|
51
|
+
background: white;
|
|
52
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Microsoft YaHei, sans-serif;
|
|
53
|
+
font-size: 18px;
|
|
54
|
+
line-height: 1.8;
|
|
55
|
+
`;
|
|
56
|
+
exportContainer.innerHTML = `
|
|
57
|
+
<style>${DEFAULT_STYLES}</style>
|
|
58
|
+
<div style="max-width: ${containerWidth - containerPadding * 2}px; margin: 0 auto;">
|
|
59
|
+
${markdownHtml}
|
|
60
|
+
</div>
|
|
61
|
+
`;
|
|
62
|
+
if (mermaidDomId) {
|
|
63
|
+
const mermaidEl = document.getElementById(mermaidDomId);
|
|
64
|
+
if (mermaidEl) {
|
|
65
|
+
const svg = mermaidEl.querySelector('svg');
|
|
66
|
+
if (svg) {
|
|
67
|
+
const svgWrapper = document.createElement('div');
|
|
68
|
+
svgWrapper.style.cssText = 'margin: 25px 0; text-align: center;';
|
|
69
|
+
const svgClone = svg.cloneNode(true);
|
|
70
|
+
svgClone.style.cssText = 'max-width: 1000px; width: 100%; height: auto;';
|
|
71
|
+
svgWrapper.appendChild(svgClone);
|
|
72
|
+
exportContainer.appendChild(svgWrapper);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
document.body.appendChild(exportContainer);
|
|
77
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
78
|
+
const containerHeight = exportContainer.scrollHeight;
|
|
79
|
+
const pageSize = PAGE_SIZES[pageFormat] || PAGE_SIZES.a4;
|
|
80
|
+
const pageWidth = orientation === 'l' ? pageSize.height : pageSize.width;
|
|
81
|
+
const pageHeight = orientation === 'l' ? pageSize.width : pageSize.height;
|
|
82
|
+
const pageContentHeight = pageHeight - padding * 2;
|
|
83
|
+
const pdf = new jsPDF({
|
|
84
|
+
orientation: orientation,
|
|
85
|
+
unit: 'mm',
|
|
86
|
+
format: pageFormat
|
|
87
|
+
});
|
|
88
|
+
const canvas = await html2canvas(exportContainer, {
|
|
89
|
+
scale: scale,
|
|
90
|
+
useCORS: true,
|
|
91
|
+
logging: false,
|
|
92
|
+
width: containerWidth,
|
|
93
|
+
height: containerHeight,
|
|
94
|
+
windowHeight: containerHeight + 100,
|
|
95
|
+
scrollY: 0
|
|
96
|
+
});
|
|
97
|
+
const imgWidth = pageWidth - padding * 2;
|
|
98
|
+
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
|
99
|
+
const pageCount = Math.ceil(imgHeight / pageContentHeight);
|
|
100
|
+
for (let i = 0; i < pageCount; i++) {
|
|
101
|
+
if (i > 0) {
|
|
102
|
+
pdf.addPage();
|
|
103
|
+
}
|
|
104
|
+
const startY = Math.floor(i * pageContentHeight * canvas.height / imgHeight);
|
|
105
|
+
const endY = Math.min(startY + Math.floor(pageContentHeight * canvas.height / imgHeight), canvas.height);
|
|
106
|
+
const pageCanvasHeight = endY - startY;
|
|
107
|
+
const pageCanvas = document.createElement('canvas');
|
|
108
|
+
pageCanvas.width = canvas.width;
|
|
109
|
+
pageCanvas.height = pageCanvasHeight;
|
|
110
|
+
const ctx = pageCanvas.getContext('2d');
|
|
111
|
+
if (ctx) {
|
|
112
|
+
ctx.fillStyle = '#ffffff';
|
|
113
|
+
ctx.fillRect(0, 0, pageCanvas.width, pageCanvas.height);
|
|
114
|
+
ctx.drawImage(canvas, 0, startY, canvas.width, pageCanvasHeight, 0, 0, pageCanvas.width, pageCanvasHeight);
|
|
115
|
+
}
|
|
116
|
+
const pageImgData = pageCanvas.toDataURL('image/jpeg', 0.95);
|
|
117
|
+
const pageImgHeight = (pageCanvasHeight / canvas.height) * imgHeight;
|
|
118
|
+
pdf.addImage(pageImgData, 'JPEG', padding, padding, imgWidth, pageImgHeight);
|
|
119
|
+
}
|
|
120
|
+
pdf.save(fileName);
|
|
121
|
+
document.body.removeChild(exportContainer);
|
|
122
|
+
return { success: true, pageCount: pageCount };
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error('生成PDF失败:', error);
|
|
126
|
+
return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { generationPDF, generationPDFWithOptions };
|
|
130
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pdf-composer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "组合多种内容生成 PDF",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "node scripts/build.js",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"markdown",
|
|
24
|
+
"pdf",
|
|
25
|
+
"pdf-composer",
|
|
26
|
+
"html2canvas",
|
|
27
|
+
"jspdf",
|
|
28
|
+
"marked"
|
|
29
|
+
],
|
|
30
|
+
"author": "xinghai.liu",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"marked": "^12.0.0",
|
|
34
|
+
"html2canvas": "^1.4.1",
|
|
35
|
+
"jspdf": "^2.5.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"typescript": "^5.3.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=16.0.0"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": ""
|
|
47
|
+
},
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": ""
|
|
50
|
+
},
|
|
51
|
+
"homepage": ""
|
|
52
|
+
}
|