【问题标题】:Convert doc to pdf using Apache POI使用 Apache POI 将 doc 转换为 pdf
【发布时间】:2013-07-23 11:30:53
【问题描述】:

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

【问题讨论】:

  • 生成的 pdf 文档仅包含文本,它没有任何格式,如图像、表格对齐方式 - 您只能获得文本,因为您只使用了 WordExtractor.getParagraphText 输出.如果您想提取样式等,则需要考虑更多信息。查看WordToHtmlConverter 了解如何提取您需要的所有数据。
  • 谢谢你的链接,你能给我一个简单的例子吗?再次感谢。
  • 您说您的任务是将 doc 转换为具有所有格式(如表格、图像、对齐方式)的 pdf。 为了进行如此完整的转换,一个示例基本上只能是另一个如此彻底的转换。如果您想要一个更简单的示例,请将您的任务缩减为本质上更简单的东西。不过,我会用更多的解释来回答这个问题。

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


【解决方案1】:

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

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

将文档转换为 pdf。

【讨论】:

    【解决方案2】:

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

    对于docx文件,docx4j可以先转成FO,再用FOP转成PDF,再转成PDF。

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

    【讨论】:

      【解决方案3】:

      手头的任务是将 doc 转换为具有所有格式(如表格、图像、对齐方式)的 pdf。

      创建自己的转换器类

      Apache POI 中已经存在WordToXxxConverter 类,即WordToFoConverterWordToHtmlConverterWordToTextConverter。后一个很可能太有损而无法作为您要求的示例,但前两个就足够了。

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

      为了实现您的任务将 doc 转换为具有所有格式(如表格、图像、对齐方式)的 pdf, 因此,您还应该从 AbstractWordConverter 派生一个转换器类,并为实现抽象方法让你会受到三个具体实现类的启发。就像在其他转换器类中一样,将特定于 PDF 库的代码集中到 PdfDocumentFacade 类中似乎是个好主意。

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

      不幸的是,这个转换器框架有点以 DOM 元素为中心:AbstractWordConverter 回调期望并转发 DOM 元素作为当前目标文档上下文的指示符;乍一看,它似乎并没有利用该上下文作为 DOM 元素,因此您可以通过复制该基类并将这些 DOM 元素参数与更合适的类型甚至更好的泛型类参数交换而侥幸。

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

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

      使用现有的转换类会更早地产生结果,但多步转换往往比单步转换损失更大。决定权在你。

      在您在问题中发布的代码中,您使用了 iText 类。 iText 确实支持使用iText XML Worker 子项目中提供的XMLWorker 从 HTML 到 PDF 的转换,但有一定的限制。在古代 iText 版本中,也曾经有现在已弃用的 HTMLWorker 类。因此,将 WordToHtmlConverter 与 iText XMLWorker 结合使用可能是您的一个选择。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-26
        • 2013-05-09
        • 1970-01-01
        相关资源
        最近更新 更多