2017-05-29 126 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