Java PDF与itext和pdfbox的合并

Java PDF与itext和pdfbox的合并,java,hibernate,itext,pdfbox,vaadin7,Java,Hibernate,Itext,Pdfbox,Vaadin7,我有一个多模块maven项目,有一个生成请求的过程,在这个过程中有一些vaadin的上传组件,我们上传的一些文档必须是png、jpgs、pdf和bmp。 现在,在这个过程的最后,我将所有的文档类型合并成一个pdf,然后用文件下载程序下载 我在按钮单击事件中调用的函数是: /** * This function is responsible for getting * all documents from request and merge * them i

我有一个多模块maven项目,有一个生成请求的过程,在这个过程中有一些vaadin的上传组件,我们上传的一些文档必须是png、jpgs、pdf和bmp。 现在,在这个过程的最后,我将所有的文档类型合并成一个pdf,然后用文件下载程序下载

我在按钮单击事件中调用的函数是:

   /**
     * This function is responsible for getting 
     * all documents from request and merge 
     * them in a single pdf file for 
     * download purposes
     * @throws Exception 
     */
    protected void downloadMergedDocument() throws Exception {

    // Calling create pdf function for merged pdf
    createPDF();

    // Setting the merged file as a resource for file downloader
    Resource myResource = new FileResource(new File (mergedReportPath +request.getWebProtocol()+ ".pdf"));
    FileDownloader fileDownloader = new FileDownloader(myResource);

    // Extending the download button for download   
    fileDownloader.extend(downloadButton);

}

/**
 * This function is responsible for providing 
 * the PDF related to a particular request that 
 * contains all the documents merged inside it 
 * @throws Exception
 */
private void createPDF() throws Exception {
    try{
        // Getting the current request
        request = evaluationRequestUI.getRequest();

        // Fetching all documents of the request            
        Collection<DocumentBean> docCollection = request.getDocuments();

        // Initializing Document of using itext library
        Document doc = new Document();

        // Setting PdfWriter for getting the merged images file
        PdfWriter.getInstance(doc, new FileOutputStream(mergedReportPath+ "/mergedImages_" + request.getWebProtocol()+ ".pdf"));

        // Opening document
        l_doc.open();

        /**
         * Here iterating on document collection for the images type   
         * document for merging them into one pdf    
         */                                        
        for (DocumentBean documentBean : docCollection) {
            byte[] documents = documentBean.getByteArray();

            if(documentBean.getFilename().toLowerCase().contains("png") ||
                    documentBean.getFilename().toLowerCase().contains("jpeg") ||
                    documentBean.getFilename().toLowerCase().contains("jpg") ||
                    documentBean.getFilename().toLowerCase().contains("bmp")){

                Image img = Image.getInstance(documents);

                doc.setPageSize(img);
                doc.newPage();
                img.setAbsolutePosition(0, 0);
                doc.add(img);
            }
        }

        // Closing the document
        doc.close();

        /**
         * Here we get all the images type documents merged into 
         * one pdf, now moving to pdfbox for searching the pdf related 
         * document types in the request and merging the above resultant      
         * pdf and the pdf document in the request into one pdf
         */

        PDFMergerUtility utility = new PDFMergerUtility();

        // Adding the above resultant pdf as a source 
        utility.addSource(new File(mergedReportPath+ "/mergedImages_" + request.getWebProtocol()+ ".pdf"));

        // Iterating for the pdf document types in the collection
        for (DocumentBean documentBean : docCollection) {
            byte[] documents = documentBean.getByteArray();

            if(documentBean.getFilename().toLowerCase().contains("pdf")){
                utility.addSource(new ByteArrayInputStream(documents));
            }
        }

        // Here setting the final pdf name
        utility.setDestinationFileName(mergedReportPath +request.getWebProtocol()+ ".pdf");

        // Here final merging and then result
        utility.mergeDocuments();

    }catch(Exception e){
        m_logger.error("CATCH", e);
        throw e;
    }
}  
/**
*此函数负责获取
*来自请求和合并的所有文档
*将它们保存在单个pdf文件中,以便
*下载目的
*@抛出异常
*/
受保护的void downloadMergedDocument()引发异常{
//调用合并pdf的创建pdf函数
createPDF();
//将合并文件设置为文件下载程序的资源
Resource myResource=newfileresource(新文件(mergedReportPath+request.getWebProtocol()+“.pdf”);
FileDownloader FileDownloader=新的FileDownloader(myResource);
//扩展下载按钮以进行下载
扩展(下载按钮);
}
/**
*此功能负责提供
*与特定请求相关的PDF
*包含其中合并的所有文档
*@抛出异常
*/
私有void createPDF()引发异常{
试一试{
//获取当前请求
请求=evaluationRequestUI.getRequest();
//获取请求的所有文档
Collection docCollection=request.getDocuments();
//使用itext库初始化文档
单据单据=新单据();
//设置PdfWriter以获取合并的图像文件
PdfWriter.getInstance(doc,新文件输出流(mergedReportPath+“/mergedImages_“+request.getWebProtocol()+”.pdf”);
//开幕文件
l_doc.open();
/**
*这里迭代图像类型的文档集合
*用于将它们合并为一个pdf的文档
*/                                        
for(DocumentBean DocumentBean:docCollection){
byte[]documents=documentBean.getByteArray();
如果(documentBean.getFilename().toLowerCase()包含(“png”)||
documentBean.getFilename().toLowerCase()包含(“jpeg”)||
documentBean.getFilename().toLowerCase()包含(“jpg”)||
documentBean.getFilename().toLowerCase()包含(“bmp”)){
Image img=Image.getInstance(文档);
文档设置页面大小(img);
doc.newPage();
img.setAbsolutePosition(0,0);
文件添加(img);
}
}
//关闭文档
doc.close();
/**
*在这里,我们将所有图像类型文档合并到
*一个pdf,现在移动到pdfbox以搜索与pdf相关的
*请求中的文档类型并合并上述结果
*pdf和请求中的pdf文档合并为一个pdf
*/
PDFMergerUtility实用工具=新的PDFMergerUtility();
//添加上述生成的pdf作为源
addSource(新文件(mergedReportPath+“/mergedImages_“+request.getWebProtocol()+”.pdf”);
//对集合中的pdf文档类型进行迭代
for(DocumentBean DocumentBean:docCollection){
byte[]documents=documentBean.getByteArray();
if(documentBean.getFilename().toLowerCase()包含(“pdf”)){
addSource(新的ByteArrayInputStream(文档));
}
}
//这里设置最终的pdf名称
setDestinationFileName(mergedReportPath+request.getWebProtocol()+“.pdf”);
//这里是最终合并,然后是结果
utility.mergeDocuments();
}捕获(例外e){
m_记录器错误(“捕捉”,e);
投掷e;
}
}  
注意:mergedReportPath是为要存储的pdf文件定义的路径,然后
从那里检索以供下载

现在,我有两个问题:

  • 当我对第一个请求执行此过程时,它会在 目标文件夹,但它不下载它
  • 当我再次对第二个请求执行此过程时,它会被卡住 实用程序.mergedocuments(),我的意思是如果它发现pdf已经 存在于目标文件夹中,它会被卡住。我不知道火车在哪里 问题是。请帮忙

  • 在问题的“评论”部分,您已澄清,您不需要磁盘上的文件,但希望将PDF发送到浏览器。你想知道如何做到这一点。官方文件对此进行了解释:

    以下是在内存中创建PDF的方法:

    // step 1
    Document document = new Document();
    // step 2
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfWriter.getInstance(document, baos);
    // step 3
    document.open();
    // step 4
    document.add(new Paragraph("Hello"));
    // step 5
    document.close();
    
    合并PDF是通过
    PdfCopy
    完成的: 您需要对这些示例应用与上述相同的原则:将
    FileOutputStream
    替换为
    ByteArrayOutputStream

    现在您有了存储在
    baos
    对象中的PDF字节。我们可以将其发送到浏览器,如下所示:

    // setting some response headers
    response.setHeader("Expires", "0");
    response.setHeader("Cache-Control",
        "must-revalidate, post-check=0, pre-check=0");
    response.setHeader("Pragma", "public");
    // setting the content type
    response.setContentType("application/pdf");
    // the contentlength
    response.setContentLength(baos.size());
    // write ByteArrayOutputStream to the ServletOutputStream
    OutputStream os = response.getOutputStream();
    baos.writeTo(os);
    os.flush();
    os.close();
    

    如果您还有其他问题,请务必阅读。

    在问题的评论部分,您已说明您不需要磁盘上的文件,但希望将PDF发送到浏览器。你想知道如何做到这一点。官方文件对此进行了解释:

    以下是在内存中创建PDF的方法:

    // step 1
    Document document = new Document();
    // step 2
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfWriter.getInstance(document, baos);
    // step 3
    document.open();
    // step 4
    document.add(new Paragraph("Hello"));
    // step 5
    document.close();
    
    合并PDF是通过
    PdfCopy
    完成的: 您需要对这些示例应用与上述相同的原则:将
    FileOutputStream
    替换为
    ByteArrayOutputStream

    现在您有了存储在
    baos
    对象中的PDF字节。我们可以将其发送到浏览器,如下所示:

    // setting some response headers
    response.setHeader("Expires", "0");
    response.setHeader("Cache-Control",
        "must-revalidate, post-check=0, pre-check=0");
    response.setHeader("Pragma", "public");
    // setting the content type
    response.setContentType("application/pdf");
    // the contentlength
    response.setContentLength(baos.size());
    // write ByteArrayOutputStream to the ServletOutputStream
    OutputStream os = response.getOutputStream();
    baos.writeTo(os);
    os.flush();
    os.close();
    

    如果您还有其他问题,请务必阅读。

    在PDFBox的2.0版本中,您可以使用
    setDestinationStream()设置输出流