JavaScript实现PDF转Word:从原理到实践

为什么需要JS实现PDF转Word?

在现代Web开发中,经常需要在浏览器端或服务器端处理文档格式转换。PDF转Word的需求尤其常见,例如:用户上传PDF简历需提取文本、文档协作平台需要可编辑格式。JavaScript作为一种全栈语言,可以高效地完成这类转换。

核心思路

PDF和Word结构差异巨大:PDF是固定布局,Word是流式文档。转换分为两步:
1. 解析PDF内容(文本、图片、表格)。
2. 生成Word文档(.docx)。
常见方案有:

  • 纯前端库组合:使用pdf.js解析PDF,再通过mammoth.jsdocx库生成Word。
  • Node.js专用库:如pdf-lib(操作PDF)、pandoc(命令行调用)或unoconv
  • 第三方API服务:如Google Docs API、ConvertAPI。

实战:使用pdf-lib + mammoth.js 前端转换

以下示例在浏览器中实现:

// 引入库(通过CDN或npm)
import * as pdfjsLib from 'pdfjs-dist';
import mammoth from 'mammoth';

async function pdfToWord(pdfUrl) {
  const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
  const textContent = [];
  for (let i = 1; i <= pdf.numPages; i++) {
    const page = await pdf.getPage(i);
    const content = await page.getTextContent();
    const pageText = content.items.map(item => item.str).join(' ');
    textContent.push(pageText);
  }
  const fullText = textContent.join('\n\n');
  // 将文本转换为HTML(mammoth需要HTML输入)
  const html = `

${fullText.replace(/\n/g, '

')}

`; // 生成.docx(mammoth.convertToHtml的反向不直接支持,此处使用docx库) // 更简单的方法:将HTML转换为Word用FileSaver保存 return new Blob([html], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); }

注意:上述代码简化了实际流程,真实场景建议使用docx库构建结构化文档,保留字体、样式等。例如用docx创建段落:

const { Document, Packer, Paragraph, TextRun } = require('docx');
const doc = new Document({
  sections: [{
    children: [
      new Paragraph({
        children: [new TextRun({ text: fullText, bold: true })],
      }),
    ],
  }],
});
const blob = await Packer.toBlob(doc);

在线API方案(推荐)

对于复杂格式(表格、图片),使用成熟API更可靠。以ConvertAPI为例:

// Node.js环境
const ConvertApi = require('convertapi')(process.env.CONVERTAPI_SECRET);

async function convert(filePath) {
  const result = await ConvertApi.convert('pdf', 'docx', { File: filePath });
  result.saveFiles('./output.docx');
}

注意事项与优化

  • 排版保留:纯文本转换会丢失布局,需提取坐标信息重建。
  • 性能:大型PDF建议丢给后端或使用Web Worker。
  • 编码问题:中文PDF需确保字体映射。

总结

JavaScript实现PDF转Word虽有一定挑战,但通过组合现有库或调用API,可满足大多数需求。根据场景灵活选择:轻量级文本用pdf.js + docx,复杂文档用专业API。未来WebAssembly的发展将使转换更高效。