2017-05-29 60 views
0

我试图生成PDF 2个数据,并把它放在一个ZIP文件中下载(通过response.getOutputStream),但我不知道如何做正确:如何将2 ByteArrayOutputStreams放入一个zip文件进行下载?

public void export() { 
    String fileName = "B2B_Price_List.zip"; 
    String fileNameUSD = "B2B_Price_List_USD.pdf"; 
    String fileNameEU = "B2B_Price_List_EU.pdf"; 

    String contentTypePDF = "application/pdf"; 
    String[] headerPDF = new String[2]; 
    headerPDF[0] = "Content-disposition"; 
    headerPDF[1] = "attachment; filename=\"" + fileNameUSD + "\""; 
    headerPDF[2] = "attachment; filename=\"" + fileNameEU + "\""; 

    String contentTypeZIP = "application/zip"; 
    String[] headerZIP = new String[1]; 
    headerZIP[0] = "Content-disposition"; 
    headerZIP[1] = "attachment; filename=\"" + fileName + "\""; 

    ByteArrayOutputStream outUSD = new ByteArrayOutputStream(); 
    outUSD = CSVHandler.downloadPriceListPDF(outUSD, fileNameUSD, ListToPDFMap(productsUSD), true); 

    ByteArrayOutputStream outEU = new ByteArrayOutputStream(); 
    outEU = CSVHandler.downloadPriceListPDF(outEU, fileNameEU, ListToPDFMap(productsEU), false); 
    // ZIP CODING GOES HERE 
} 

该函数返回ByteArrayOutputStream到在以后使用:

public static ByteArrayOutputStream downloadPriceListPDF 
    (ByteArrayOutputStream output, final String filename, 
    Map<String, Map<String, List<B2BProductData>>> datas, 
    boolean amerCustomer) { 
    try { 
     PdfDocument pdfDoc = null; 
     try { 
      pdfDoc = new PdfDocument(new PdfWriter(output));  

      PageSize pageSize = new PageSize(PageSize.A4); 
      Document doc = new Document(pdfDoc, pageSize, false); 
      PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage()); 

      String coverImage = COVER_IMAGE; 
      if(!amerCustomer) { 
       coverImage = COVER_IMAGE_1; 
      } 

      canvas.addImage(ImageDataFactory.create(CSVHandler.class.getClassLoader().getResource(coverImage).getPath()), pageSize, false); 

      // loop thru category 
      int pageNo = 2; 
      Map<String, List<B2BProductData>> inputDatas = new LinkedHashMap<>(); 
      for(String category : datas.keySet()) { 
       Map<String, List<B2BProductData>> prods = datas.get(category); 

       while(true) { 
        inputDatas = new LinkedHashMap<>();     
        Map<String, List<B2BProductData>> remaindatas = filterDatas(inputDatas, prods); 

        if(inputDatas.size() > 0) { 
         createPDFPage(pdfDoc, doc, category, inputDatas, pageNo ++, amerCustomer); 
        } 

        if(remaindatas.size() > 0) { 
         prods = remaindatas; 
        } else { 
         break; 
        } 
       } 
      }   

      doc.close(); 

      return output; 
     } catch (IOException e) { 
      LOG.error(e.getMessage()); 
      return output; 
     } 
    } 
    catch (final Exception ex) { 
     LOG.error("Export Products got error: " + ex.getMessage()); 
     return output; 
    } 
} 
+1

您可能还需要修改你的问题,删除您iText的标签和iText的代码,因为你的问题仅是关于拉链,它并不真正的问题你通过什么它。 – sorifiend

+0

[使用Java ByteArrayOutputstream压缩文件]的可能重复(https://stackoverflow.com/questions/26482779/compress-file-with-java-bytearrayoutputstream) – sorifiend

+0

同意,更改您的标题和标签以吸引更多的观众,他们可能能够帮助。 –

回答

2

我做了这样的:

申报的文件名,以供以后使用。

   String fileName = "B2B_Price_List.zip"; 
       String fileNameUSD = "B2B_Price_List_USD.pdf"; 
       String fileNameEU = "B2B_Price_List_EU.pdf"; 

声明一个新的ByteArrawOutputStream类并使用“new”进行初始化。

   ByteArrayOutputStream outUSD = new ByteArrayOutputStream(); 
       ByteArrayOutputStream outEU = new ByteArrayOutputStream(); 

生成PDF文件后,返回值ByteArrayOutputStream并分配给之前声明的ByteArrayStream。

   if (hasUSD) outUSD = CSVHandler.generatePriceListPDF(outUSD, ListToPDFMap(productsUSD), true, true); 
       if (hasEU) outEU = CSVHandler.generatePriceListPDF(outEU, ListToPDFMap(productsEU), false, true); 

声明的OutputStream被用来保持响应对象的输出流。

   OutputStream responseOutputStream; 

声明头字符串将被分配给该响应对象的标题数据。在这种情况下,对于zip文件,MIME类型将是application/zipfileNameB2B_Price_List.zip)也用于定义下载的文件名。

    String contentTypeZIP = "application/zip"; 
        String[] headerZIP = new String[1]; 
        headerZIP[0] = "Content-disposition"; 
        headerZIP[1] = "attachment; filename=\"" + fileName + "\""; 

设置响应对象的头。

    response.setContentType(contentTypeZIP); 
        response.setHeader(headerZIP[0], headerZIP[1]); 

设置responseOutputStream举行响应对象的OutputStream。

    responseOutputStream = response.getOutputStream(); 

声明一个ZipOutputStream,并与响应的的OutputStream作为参数初始化。该参数将用于写入以便在此处写入稍后要下载的文件,在这种情况下为ZIP文件。

    ZipOutputStream zos = new ZipOutputStream(responseOutputStream); 

声明ZIP文件要放的ZipEntry对象。使用文件名字符串作为参数初始化新的。在这种情况下,我们会将例如文件放入ZIP文件中。

    ZipEntry zipEntryUSD = new ZipEntry(fileNameUSD); 
        ZipEntry zipEntryEU = new ZipEntry(fileNameEU); 

把每个项(或文件),一次一个,在putNextEntry被称为一个条目后,再假定,未来.WRITE称为将被写入到以前条目。

在这种情况下,我们称之为.WRITEByteArrayOutputStream.toByteArray()转换为的ByteArray作为参数。不要忘记通过调用.closeEntry()来关闭条目,然后使用相同的过程前进到下一个文件。

    zos.putNextEntry(zipEntryUSD); 
        zos.write(outUSD.toByteArray()); 
        zos.closeEntry(); 

        zos.putNextEntry(zipEntryEU); 
        zos.write(outEU.toByteArray()); 
        zos.closeEntry(); 

写你所需要的ZIP里面的条目(文件)后,不要忘记关闭ZipOutputStreamZOS在这种情况下)。

    zos.close(); 

那么该文件将继续下载您刷新/接近响应的输出流之后。您可能会忽略冲洗但可以肯定的是,无论如何我都将其包含在内。码块的

    responseOutputStream.flush(); 
        responseOutputStream.close(); 

END


CSVHandler.generatePriceListPDF

现在,这是用于产生PDF>到>ByteArrayOutputStream的功能。我们通过输出对象从以前的ByteArrayOutputStream被重新分配给该函数外传递的ByteArrayOutputStream对象。

例如:

outUSD = CSVHandler.generatePriceListPDF(outUSD,ListToPDFMap(productsUSD),真,TRUE);

功能块START

public static ByteArrayOutputStream downloadPriceListPDF 
    (ByteArrayOutputStream output, final String filename, 
    Map<String, Map<String, List<B2BProductData>>> datas, 
    boolean amerCustomer, boolean autoCloseByteArrayOutputStream) { 
    try { 
     PdfDocument pdfDoc = null; 
     try { 

初始化作家作为与ByteArrayOutputStream作为参数新PdfWriter,在这种情况下,输出函数参数对象。

  PdfWriter writer = new PdfWriter(output); 

初始化pdfDoc新PdfDocument与PdfWriter对象作家在这种情况下,作为参数。这指示pdfDoc到直接写入ByteArrayOutputStream(输出)对象

  pdfDoc = new PdfDocument(writer);  

初始化PDF文件的参数,例如大小和这样。

  PageSize pageSize = new PageSize(PageSize.A4); 
      Document doc = new Document(pdfDoc, pageSize, false); 
      PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage()); 

这是编写PDF,数据,图像或任何东西的部分。

  // YOUR OWN PDF WRITE OPERATION HERE 

不要忘记在写完东西后关闭PDF文档。

  doc.close(); 

函数参数autoCloseByteArrayOutputStream布尔我加了决定,如果你想关闭ByteArrayOutputStream此类函数内部,还是外部关闭它,如果你想在外面的内容补充。您的选择,但不要忘记关闭ByteArrayOutputStream总是无论如何。

 If (autoCloseByteArrayOutputStream) { 
      output.flush(); 
      output.close(); 
     } 

返回的输出ByteArrayOutputStream

  return output; 
     } catch (IOException e) { 

如果发生异常,在所有代码路径上返回一个对象是很重要的。在这种情况下,我们返回nullByteArrayOutputStream发生错误。

  LOG.error(e.getMessage()); 
      return output; 
     } 
    } 
    catch (final Exception ex) { 

同样在这里,误差错误的情况下返回ByteArrayOutputStream

 LOG.error("Export Products got error: " + ex.getMessage()); 
     return output; 
    } 
} 

END功能块的

+0

请在回答中添加一些解释 –

+1

为您服务。 – jestrange