使用Apache POI将doc转换为pdf

时间:2013-07-24 06:08:32

标签: java pdf pdf-generation apache-poi doc

我正在尝试使用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();  
         }  
     }  
 }

3 个答案:

答案 0 :(得分:8)

手头的任务是将doc转换为pdf,其中包含所有格式,如表格,图像,路线。

创建自己的转换器类

Apache POI中已有WordToXxxConverter个类,即WordToFoConverterWordToHtmlConverterWordToTextConverter。后者很可能太过有损而无法满足您的要求,但前两者就足够了。

所有这些转换器类都派生自公共基类AbstractWordConverter,它为字转换类提供了基本框架。此外,所有这些类都使用匹配的*DocumentFacade类,它包装具体的目标(或某些中间)格式创建:FoDocumentFacadeHtmlDocumentFacadeTextDocumentFacade

要实现您的任务将doc转换为pdf并具有所有格式,例如表格,图像,路线,,因此您还应该从AbstractWordConverter派生转换器类并实现摘要方法让自己受到三个具体实现类的启发。就像在其他转换器类中一样,将特定于PDF库的特定代码集中到PdfDocumentFacade类似乎是一个好主意。

如果您想稍微开始并稍后添加更复杂的细节,您可以先使用很多WordToTextConverter实现代码,并且一旦至少在概念验证级别上工作,请扩展功能还可以涵盖越来越多的格式信息。

不幸的是,这个转换器框架在某种程度上以DOM元素为中心:AbstractWordConverter回调期望并转发DOM元素作为当前目标文档上下文的指示符;乍一看它似乎没有使用该上下文作为DOM元素,因此您可能会复制该基类并使用更多的apropos类型或甚至更好的泛型类参数交换这些DOM元素参数。

将现有的Word-to-XXX转换器与现有的XXX-to-Pdf转换器结合使用

如果这对您的资源来说似乎过于复杂或耗时,您可以尝试不同的方法:您可以尝试使用上面提到的某个现有转换器的输出作为另一个转换为Pdf的输入。

使用现有的转换类会提前得出结果,但多步转换往往比单步转换更有损。决定取决于你。

在您在问题中发布的代码中,您使用了iText类。 iText确实支持使用iText XML Worker子项目中提供的XMLWorker将HTML从HTML转换为具有某些限制。在古代iText版本中,过去曾经被弃用的HTMLWorker类。因此,将WordToHtmlConverter与iText XMLWorker结合使用可能是您的选择。

另外,Apache还提供对PDF的XSL FO处理。这适用于WordToFoConverter的输出也可能是一个选项

答案 1 :(得分:2)

作为POI的替代方案(但仍在Java域中),您可以考虑使用docx4j(我领导/维护)。

对于docx文件,docx4j可以通过首先转换为FO,然后使用FOP转换为PDF来转换为PDF。

对于旧版二进制文档文件(以及docx文件),我们有一个高性能的商业解决方案。您可以在http://converter-eval.plutext.com/plutext/converter尝试,或在http://www.plutext.com/m/index.php/products-docx-to-pdf.html

获取更多信息

答案 2 :(得分:1)

我使用OpenOffice / LibreOffice导出为PDF,它有一些自动化支持,例如

unoconv -vvv --timeout=10 --doctype=document --output=result.pdf result.docx

会将doc转换为pdf。