【问题标题】:How can i zip multiple pdf files in Primefaces?如何在 Primefaces 中压缩多个 pdf 文件?
【发布时间】:2020-07-27 18:38:45
【问题描述】:

我想压缩在数据表中选择的多个 pdf 文件并让用户下载它们。

这里是 XHTML;

<p:commandLink id="print_orders" 

        value="Print Selected Orders" ajax="false" 
        onclick="PrimeFaces.monitorDownload(startPrint, stopPrint);"  
        styleClass="button button--ujarak button--border-thin button--text-medium download"
        style="text-align: center;  float:none; margin: 0px auto 0px auto; padding: 0.05em 0.1em;" >
                            
        <p:fileDownload value="#{printOrdersManagedBeanSAP.printsAction()}" />

</p:commandLink>

让我澄清一下 managedbean 方面;

purchaseOrder 对象包括 PO_NUMBER() 我使用 PO_NUMBER() 从 SAP 生成 pdf 文档 (pdfDoc) 作为 ByteArrayOutputStream。使用 for 循环,我尝试生成包含与所选列一样多的 pdf 文档的 zip 文件。顺便说一句,我不确定我做对了。

带“返回(StreamedContent)输出;”代码块我试图返回 zip 文件,但我得到“java.util.zip.ZipOutputStream 无法转换为 org.primefaces.model.StreamedContent”异常。由于 Primefaces 标记,我尝试将 ZipOutputStream 转换为 StreamedContent。

你能帮我解决这个问题吗?

 public StreamedContent printsAction()
{
    if(!termsAgreed)
        RequestContext.getCurrentInstance().execute("PF('warningDialog').show();");
    else
    {
        if (getSelectedPurchaseOrders() != null && !getSelectedPurchaseOrders().isEmpty()) {
            
            try
            {
                FileOutputStream zipFile = new FileOutputStream(new File("PO_Reports.zip"));
                ZipOutputStream output   = new ZipOutputStream(zipFile);
                
                for (PurchaseOrderSAP purchaseOrder : getSelectedPurchaseOrders()) {
                    
                    ByteArrayOutputStream pdfDoc = purchaseOrderSAPService.printOrder(selectedPurchaseOrder.getPO_NUMBER());
                    
                    ZipEntry zipEntry = new ZipEntry(purchaseOrder.getPO_NUMBER());
                    output.putNextEntry(zipEntry);
                    
                    InputStream targetStream = new ByteArrayInputStream(pdfDoc.toByteArray());
                    
                    IOUtils.copy(targetStream, output);
                    output.closeEntry();
                }
                
                output.finish();
                output.close();
                return (StreamedContent) output;
                
                
            }       
            catch(Exception ex)
            {
                    System.out.println("error when generating...");
                    ex.printStackTrace();
            }
            
        }
    }
    
    return null;
}

【问题讨论】:

  • 压缩多个 pdf 文件与压缩多个 txt 文件相同,不是 PrimeFaces,而是纯 java。发送一个压缩的 pdf 或普通的非压缩 pdf 或 txt 文件时也会出现错误。尝试...并查看关于如何使用 StreamedContent 的 PF 展示。投射!= 转换

标签: java jsf primefaces


【解决方案1】:

您不能简单地将ZipOutputStream转换StreamedContent,因为它们没有父子关系。见How can I cast objects that don't inherit each other?

您应该将您的InputStream(不是输出流)转换为流式传输内容。参见例如https://www.primefaces.org/showcase/ui/file/download.xhtml

因此,您需要执行以下操作:

DefaultStreamedContent.builder()
                .name("PO_Reports.zip")
                .contentType("application/zip")
                .stream(() -> yourInputStream)
                .build();

【讨论】:

    【解决方案2】:

    我找到了这些问题的解决方案。也许这个解决方案会帮助别人。对于新解决方案的任何贡献,我将不胜感激。

    public StreamedContent printsAction() {
        ByteArrayInputStream bis = null;
        InputStream stream = null;
        if (!termsAgreed) {
            RequestContext.getCurrentInstance().execute("PF('warningDialog').show();");
        } else {
            if (getSelectedPurchaseOrders() != null && !getSelectedPurchaseOrders().isEmpty()) {
                try {
                    if (zipBytes() != null) {
                        bis = new ByteArrayInputStream(zipBytes()); // Firstly I zip every PDF doc with zipBytes() method
                        stream = bis;
                        file = new DefaultStreamedContent(stream, "application/zip", "PO_Reports.zip",StandardCharsets.UTF_8.name());
                        return file;
                    } else {
                        return null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (bis != null) {
                            bis.close();
                        }
                        if (stream != null) {
                            stream.close();
                        }
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
            } else {
                return null;
            }
        }
        return null;
    }
    
    private byte[] zipBytes() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ByteArrayOutputStream pdfDoc = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(baos);
        DataInputStream pdfDocIs = null;
        byte[] result = null;
        try {
            for(PurchaseOrderSAP purchaseOrder : getSelectedPurchaseOrders()) {
                pdfDoc = purchaseOrderSAPService.printOrder(purchaseOrder.getPO_NUMBER()); // PDF document comes from SAP as ByteArrayOutputStream
                pdfDocIs = new DataInputStream(new ByteArrayInputStream(pdfDoc.toByteArray()));
                ZipEntry zipEntry = new ZipEntry("PO_Report_" + purchaseOrder.getPO_NUMBER() + ".pdf");
                zos.putNextEntry(zipEntry);
                zos.write(toByteArray(pdfDocIs)); // Secondly in order to zip PDF doc i convert it to Byte Array with toByteArray method
            }
            zos.close();
            result =  baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (baos != null) {
                    baos.close();
                }
                if (pdfDoc != null) {
                    pdfDoc.close();
                }
                if (zos != null) {
                    zos.close();
                }
                if (pdfDocIs != null) {
                    pdfDocIs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    
    public static byte[] toByteArray(InputStream in) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        byte[] result = null;
        int len;
        // read bytes from the input stream and store them in buffer
        try {
            while ((len = in.read(buffer)) != -1) {
                // write bytes from the buffer into output stream
                os.write(buffer, 0, len);
            }
            result = os.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    

    【讨论】:

    • 为什么要创建两次zip?
    • 我以为我用 zos 创建了一个 zip 文件并将 pdf 放入 zos。第二个 zip 文件是哪个?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多