使用Apache POI将doc转换为pdf

6
我正在尝试使用Apache POI将doc转换为pdf,但生成的pdf文档仅包含文本,没有任何格式,如图像、表格对齐等。
我该如何在转换doc到pdf时保留所有格式,如表格、图像、对齐等?
以下是我的代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;


import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;

import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class demo {
    public static void main(String[] args) {

        POIFSFileSystem fs = null;  
        Document document = new Document();

         try {  
             System.out.println("Starting the test");  
             fs = new POIFSFileSystem(new FileInputStream("Resume.doc"));  

             HWPFDocument doc = new HWPFDocument(fs);  
             WordExtractor we = new WordExtractor(doc);  

             OutputStream file = new FileOutputStream(new File("test.pdf")); 

             PdfWriter writer = PdfWriter.getInstance(document, file);  

             Range range = doc.getRange();
             document.open();  
             writer.setPageEmpty(true);  
             document.newPage();  
             writer.setPageEmpty(true);  

             String[] paragraphs = we.getParagraphText();  
             for (int i = 0; i < paragraphs.length; i++) {  

                 org.apache.poi.hwpf.usermodel.Paragraph pr = range.getParagraph(i);
                 paragraphs[i] = paragraphs[i].replaceAll("\\cM?\r?\n", "");  
                 System.out.println("Length:" + paragraphs[i].length());  
                 System.out.println("Paragraph" + i + ": " + paragraphs[i].toString());  
                 // add the paragraph to the document  
                 document.add(new Paragraph(paragraphs[i]));  
             }  

             System.out.println("Document testing completed");  
         } catch (Exception e) {  
             System.out.println("Exception during test");  
             e.printStackTrace();  
         } finally {  
             // close the document  
             document.close();  
         }  
     }  
 }

5
生成的 PDF 文档只包含文本,没有图片、表格或对齐等格式。这是因为您只使用了“WordExtractor.getParagraphText”输出,如果您想提取样式等其他信息,则需要考虑更多信息。请参考“WordToHtmlConverter”以获取提取所需数据的想法。 - mkl
谢谢您提供的链接,您能给我一个简单的例子吗?再次感谢。 - user1710922
你说你的任务是将文档转换为PDF,并保留所有格式,如表格、图片和对齐方式。要完成这样完整的转换,实际上只能提供另一个完整的转换作为示例。如果你想要一个更简单的示例,可以将你的任务简化为本质上更简单的内容。我会在答案中加入更多解释。 - mkl
3个回答

8
任务是将文档转换为PDF,并保留所有格式,如表格、图像和对齐方式。
创建自己的转换器类
Apache POI 中已经有了 WordToXxxConverter 类,即 WordToFoConverterWordToHtmlConverterWordToTextConverter。后者很可能过于损失以满足您的要求,但前两者则是适当的选择。
所有这些转换器类都派生自公共基类AbstractWordConverter,该基类为单词转换类提供了基本框架。此外,所有这些类都使用匹配的*DocumentFacade类,该类包装了具体目标(或某些中间)格式的创建:FoDocumentFacadeHtmlDocumentFacadeTextDocumentFacade
为了实现您的任务,即将doc转换为pdf并保留所有格式,如表格、图片、对齐等,因此您还应该从AbstractWordConverter派生一个转换器类,并通过三个具体的实现类来启发自己实现抽象方法。就像其他转换器类一样,将非常PDF库特定的代码集中到PdfDocumentFacade类中似乎是一个好主意。
如果您想简单开始并稍后添加更复杂的细节,可以首先使用WordToTextConverter实现代码,并在至少在概念验证级别上工作时,扩展功能以覆盖越来越多的格式信息。
很不幸,这个转换框架有点以DOM元素为中心: AbstractWordConverter 回调期望并将DOM元素作为当前目标文档上下文的指示器; 乍一看,它似乎没有利用DOM元素的上下文,因此您可以复制该基类并将那些DOM元素参数替换为更合适的类型甚至更好的通用类参数。
使用现有的Word-to-XXX转换器与现有的XXX-to-Pdf转换器结合使用
如果这对您的资源来说过于复杂或耗时,您可以尝试另一种方法: 您可以尝试将上述现有转换器之一的输出用作另一个转换到Pdf的输入。
使用现有的转换类将更早地获得结果,但多步转换往往比单步转换更容易丢失信息。决定权在您手中。
在您发布的问题中,您使用了iText类。 iText使用iText XML Worker子项目中提供的XMLWorker支持从HTML转换为PDF,但存在某些限制。在古老的iText版本中,还曾经有过现在已弃用的HTMLWorker类。因此,将WordToHtmlConverter与iText XMLWorker结合使用可能是您的选择之一。
此外,Apache还提供XSL FO处理到PDF。这适用于WordToFoConverter的输出,也可能是一种选择。

2
作为 POI 的替代方案(但仍在 Java 领域内),您可以考虑使用 docx4j(我是其领导/维护者)。对于 docx 文件,docx4j 可以通过首先转换为 FO,然后使用 FOP 转换为 PDF 来进行转换。对于传统的二进制文档文件(以及 docx 文件),我们有一个高性能的商业解决方案。您可以在 http://converter-eval.plutext.com/plutext/converter 上尝试该解决方案,或在 http://www.plutext.com/m/index.php/products-docx-to-pdf.html 上获取更多信息。

1
我使用OpenOffice/LibreOffice进行PDF导出,它具有一些自动化支持,例如:类似于
unoconv -vvv --timeout=10 --doctype=document --output=result.pdf result.docx

将文档转换为PDF格式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接