代码之家  ›  专栏  ›  技术社区  ›  tushar sharma

使用itext和pdfbox合并PDF

  •  0
  • tushar sharma  · 技术社区  · 9 年前

    我有一个多模块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;
        }
    }  
    

    注意:mergedReportPath是为要存储的pdf文件定义的路径,然后
    从那里检索以供下载。

    现在,我有两个问题:

    1. 当我为第一个请求执行此过程时,它会在 目标文件夹,但它不会下载它。
    2. 当我再次为第二个请求执行此过程时,它被卡住了 实用程序。mergedocuments(),我的意思是如果它发现pdf已经 出现在目标文件夹中,它会被卡住。我不知道在哪里 问题是。请帮助
    2 回复  |  直到 9 年前
        1
  •  2
  •   Community CDub    8 年前

    在2.0版本的PDFBox中,可以使用 setDestinationStream() 因此,您只需拨打

    response.setContentType("application/pdf");
    OutputStream os = response.getOutputStream();
    utility.setDestinationStream(os);
    utility.mergeDocuments();
    os.flush();
    os.close();
    

    您不能这样设置响应大小;如果必须,请使用 ByteArrayOutputStream 就像布鲁诺的回答或 this one .

        2
  •  0
  •   Bruno Lowagie    9 年前

    在问题的评论部分,您已经澄清了您不需要磁盘上的文件,但您想将PDF发送到浏览器。你想知道如何做到这一点。官方文件对此进行了解释: How can I serve a PDF to a browser without storing a file on the server side?

    以下是在内存中创建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 : How to merge documents correctly? 您需要对这些示例应用与上面相同的原则:替换 FileOutputStream ByteArrayOutputStream .

    现在您有了存储在 baos 对象我们可以这样发送到浏览器:

    // 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();
    

    确保阅读 documentation 如果你还有其他问题。