Files
FunMD_Convert/docling/PDF_API_USAGE.md
2026-01-13 22:56:22 +08:00

426 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Word/Markdown 转 PDF API 使用指南
## API 端点
```
POST /api/pdf/convert
```
## 支持的输入方式
### 1. 上传文件
支持上传 `.doc`, `.docx`, `.md` 文件:
```javascript
// 上传 Word 文件
const formData = new FormData();
formData.append('file', fileInput.files[0]); // .doc 或 .docx
// 可选参数
formData.append('toc', 'true'); // 生成目录
formData.append('header_text', '文档标题|页码'); // 页眉
formData.append('footer_text', '版权信息'); // 页脚
formData.append('filename_text', '我的文档'); // 文件名
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
```
### 2. 指定本地文件路径
```javascript
const formData = new FormData();
formData.append('file_path', '/path/to/document.docx');
formData.append('toc', 'true');
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
```
### 3. 直接提交 Markdown 内容
```javascript
const formData = new FormData();
formData.append('markdown_content', '# 标题\n\n这是内容');
formData.append('filename_text', '我的文档');
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
```
## 完整参数列表
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file | File | 否* | 上传的文件 |
| file_path | string | 否* | 本地文件路径 |
| markdown_content | string | 否* | Markdown 内容 |
| toc | boolean | 否 | 是否生成目录,默认 false |
| header_text | string | 否 | 页眉文本,可用 `\|` 分隔左右 |
| footer_text | string | 否 | 页脚文本 |
| logo_url | string | 否 | Logo 图片 URL |
| copyright_text | string | 否 | 版权声明 |
| filename_text | string | 否 | 显示的文件名 |
| cover_src | string | 否 | 封面图片 URL |
| product_name | string | 否 | 产品名称(封面) |
| document_name | string | 否 | 文档名称(封面) |
| product_version | string | 否 | 产品版本 |
| document_version | string | 否 | 文档版本 |
| css_name | string | 否 | CSS 样式名称 |
| css_text | string | 否 | 自定义 CSS |
| download | boolean | 否 | 是否直接下载,默认 true |
*注file、file_path、markdown_content 三者必选其一
## 完整示例代码
### React 示例
```jsx
import { useState, useRef } from 'react';
function PdfConverter() {
const [loading, setLoading] = useState(false);
const fileInput = useRef(null);
const convertToPdf = async () => {
const file = fileInput.current.files[0];
if (!file) return;
setLoading(true);
const formData = new FormData();
formData.append('file', file);
formData.append('toc', 'true');
formData.append('header_text', '我的文档|第 {page} 页');
formData.append('footer_text', '© 2024 公司名称');
formData.append('filename_text', file.name.replace(/\.[^/.]+$/, ''));
try {
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || '转换失败');
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
// 下载 PDF
const a = document.createElement('a');
a.href = url;
a.download = file.name.replace(/\.[^/.]+$/, '') + '.pdf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error('转换失败:', error);
alert('转换失败: ' + error.message);
} finally {
setLoading(false);
}
};
return (
<div>
<input
type="file"
ref={fileInput}
accept=".doc,.docx,.md"
/>
<button
onClick={convertToPdf}
disabled={loading}
>
{loading ? '转换中...' : '转换为 PDF'}
</button>
</div>
);
}
```
### Vue 3 示例
```vue
<template>
<div>
<input
ref="fileInput"
type="file"
accept=".doc,.docx,.md"
/>
<button
@click="convertToPdf"
:disabled="loading"
>
{{ loading ? '转换中...' : '转换为 PDF' }}
</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const fileInput = ref(null);
const loading = ref(false);
const convertToPdf = async () => {
const file = fileInput.value.files[0];
if (!file) return;
loading.value = true;
const formData = new FormData();
formData.append('file', file);
formData.append('toc', 'true');
formData.append('header_text', '我的文档');
formData.append('filename_text', file.name.replace(/\.[^/.]+$/, ''));
try {
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || '转换失败');
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = file.name.replace(/\.[^/.]+$/, '') + '.pdf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error('转换失败:', error);
alert('转换失败: ' + error.message);
} finally {
loading.value = false;
}
};
</script>
```
### 原生 JavaScript 示例
```html
<!DOCTYPE html>
<html>
<head>
<title>Word/Markdown 转 PDF</title>
</head>
<body>
<h1>文档转 PDF</h1>
<input type="file" id="fileInput" accept=".doc,.docx,.md">
<button id="convertBtn">转换为 PDF</button>
<div id="status" style="margin-top: 10px;"></div>
<script>
document.getElementById('convertBtn').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
const status = document.getElementById('status');
const file = fileInput.files[0];
if (!file) {
status.textContent = '请选择文件';
return;
}
status.textContent = '转换中...';
const formData = new FormData();
formData.append('file', file);
formData.append('toc', 'true');
formData.append('header_text', '我的文档|{page}');
formData.append('footer_text', '© 2024');
formData.append('filename_text', file.name.replace(/\.[^/.]+$/, ''));
try {
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || '转换失败');
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = file.name.replace(/\.[^/.]+$/, '') + '.pdf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
status.textContent = '转换成功!';
} catch (error) {
console.error(error);
status.textContent = '转换失败: ' + error.message;
}
});
</script>
</body>
</html>
```
### Markdown 内容转 PDF 示例
```javascript
async function markdownToPdf() {
const markdownContent = `
# 我的文档
## 第一章
这是第一章的内容。
### 小节
- 列表项 1
- 列表项 2
| 列1 | 列2 |
|-----|-----|
| A | B |
`;
const formData = new FormData();
formData.append('markdown_content', markdownContent);
formData.append('filename_text', '我的Markdown文档');
formData.append('toc', 'true');
formData.append('header_text', 'Markdown文档');
formData.append('footer_text', '© 2024');
const response = await fetch('/api/pdf/convert', {
method: 'POST',
body: formData
});
const blob = await response.blob();
// 保存 PDF
saveAs(blob, 'document.pdf');
}
```
## Python 调用示例
```python
import requests
def convert_word_to_pdf(file_path, output_path):
"""将 Word 文件转换为 PDF"""
with open(file_path, 'rb') as f:
files = {'file': f}
data = {
'toc': 'true',
'header_text': '我的文档',
'footer_text': '© 2024',
'filename_text': '文档名称'
}
response = requests.post(
'http://localhost:8000/api/pdf/convert',
files=files,
data=data
)
if response.status_code == 200:
with open(output_path, 'wb') as out:
out.write(response.content)
print(f"PDF 已保存到: {output_path}")
else:
print(f"转换失败: {response.text}")
# 使用示例
convert_word_to_pdf('document.docx', 'output.pdf')
```
## cURL 示例
```bash
# 上传 Word 文件转 PDF
curl -X POST http://localhost:8000/api/pdf/convert \
-F "file=@document.docx" \
-F "toc=true" \
-F "header_text=我的文档" \
-F "footer_text=© 2024" \
-o output.pdf
# Markdown 内容转 PDF
curl -X POST http://localhost:8000/api/pdf/convert \
-F "markdown_content=# 标题\n\n这是内容" \
-F "filename_text=文档" \
-o output.pdf
```
## 错误处理
API 返回的错误格式:
```json
{
"detail": "错误信息"
}
```
常见错误:
| 错误信息 | 原因 | 解决方法 |
|---------|------|----------|
| 必须提供 file、file_path 或 markdown_content 中的一个 | 未提供输入 | 检查请求参数 |
| 不支持的文件格式 | 文件格式错误 | 确保是 .doc/.docx/.md |
| 文件不存在 | 本地文件路径无效 | 检查 file_path 参数 |
| PDF 转换失败 | 转换过程出错 | 查看服务器日志 |
## 返回格式
### download=true (默认)
直接返回 PDF 文件流:
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"
```
### download=false
返回 JSON包含 base64 编码的 PDF
```json
{
"ok": true,
"pdf_base64": "JVBERi0xLjQK...",
"filename": "document.pdf",
"size": 12345
}
```