2013-12-12 2 views
0

우선 불쌍한 코딩을 용서해주십시오!
메모리 파일에서 디스크에 Zip 파일 만들기

요구 사항 :
1./XLS 만들기 데이터베이스의 ResultSet에서 메모리에 보고서를 XLSX (. 즉, 일반 텍스트 파일은 디스크에 기록되어서는 안된다).
2. 디스크의 ZIP 만들기 메모리의 xlsx 파일에서.

환경 :
제가 아파치의 POI 및 Zip4j을 이용하고 있고 Mr.Shrikant의 예는 "http://www.lingala.net/zip4j/forum/index.php?topic=257.0"

에 게시 다음입니다

WINXP SP2, JDK1.6_06, Zip4j1.3.1, poi3.8

관찰 :
1.이 프로그램은 샘플 데이터를 위해 27,842 바이트 xlsx 파일을 디스크에 씁니다.
2. 동일한 통합 문서가 ByteArrayOutputStream을 만듭니다. baoStream 크기는 49022 바이트입니다.
3. 암호화 및 압축 후 크기가 43,084 바이트 인 파일을 만듭니다. 4.
Zip 파일을 추출하는 동안은,
A)에서 WinZip,
b)는 WinRAR과 오류 "예기치 않은 파일의 끝을"던져 "CRC 오류"

정정 해줘, 내가 잘못 어디서나 개선하십시오 던졌습니다 내가 가난한 곳이면 어디든!

미리 감사드립니다.

package zipconversion; 

import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.Statement; 
import java.sql.Types; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

import java.util.Random; 
import net.lingala.zip4j.io.ZipOutputStream; 
import net.lingala.zip4j.model.ZipParameters; 
import net.lingala.zip4j.util.Zip4jConstants; 
import org.apache.poi.ss.usermodel.CellStyle; 
import org.apache.poi.xssf.usermodel.XSSFCell; 
import org.apache.poi.xssf.usermodel.XSSFCellStyle; 
import org.apache.poi.xssf.usermodel.XSSFColor; 
import org.apache.poi.xssf.usermodel.XSSFFont; 
import org.apache.poi.xssf.usermodel.XSSFRow; 
import org.apache.poi.xssf.usermodel.XSSFSheet; 
import org.apache.poi.xssf.usermodel.XSSFWorkbook; 

public class ZipCreationInMemory { 

    ZipOutputStream zos = null; 
    XSSFWorkbook workbook = null; 
    ByteArrayOutputStream baoStream = null; 
    String path = null; 
    String xlsxfileExtn = null; 
    String zipfileExtn = null; 
    String onlyFileName = null; 
    String xlsxFileName = null; 
    String zipFileName = null; 
    String xlsxFilePath = null; 
    String zipFilePath = null; 

    public static int randInt(int min, int max) { 
     Random rand = new Random(); 
     int randomNum = rand.nextInt((max - min) + 1) + min; 
     return randomNum; 
    } 

    public void createXlsxFile() { 
     try { 
      SimpleDateFormat timeFormat = new SimpleDateFormat("hh_mm_ss"); 
      path = "D:\\abcd\\"; 
      xlsxfileExtn = ".xlsx"; 
      zipfileExtn = ".zip"; 
      onlyFileName = "ReportData_".concat(timeFormat.format(new Date())); 
      xlsxFileName = onlyFileName + xlsxfileExtn; 
      zipFileName = onlyFileName + zipfileExtn; 
      xlsxFilePath = path + xlsxFileName; 
      zipFilePath = path + zipFileName; 
      FileOutputStream out = new FileOutputStream(new File(xlsxFilePath)); 
      workbook = new XSSFWorkbook(); 
      XSSFSheet sheet = workbook.createSheet("Report"); 
      XSSFRow rowHead = sheet.createRow((short) 0); 

      XSSFCellStyle headStyle = workbook.createCellStyle(); 
      XSSFFont headerFont = workbook.createFont(); 
      headerFont.setBold(true); 
      headerFont.setColor(new XSSFColor(new java.awt.Color(255, 0, 0))); 
      headStyle.setFont(headerFont); 
      headStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 255, 255))); 
      headStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); 

      XSSFCellStyle oddStyle = workbook.createCellStyle(); 
      oddStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(randInt(125, 255), randInt(125, 255), randInt(125, 255)))); 
      oddStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); 

//JDBC CONFIGURATIONS 
      Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance(); 
      String dbURL = "jdbc:derby://localhost:1527/DATABASE_NAME;create=true;user=USER_ID;password=PASSWORD"; 

      Connection connection = DriverManager.getConnection(dbURL); 
      Statement st = connection.createStatement(); 
      ResultSet resultSet = st.executeQuery("Select * from TABLE_NAME"); 
      ResultSetMetaData metaData = resultSet.getMetaData(); 
      int colCount = metaData.getColumnCount(); 

      SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss"); 



      for (int curColIndx = 0; curColIndx < colCount; curColIndx++) { 
       XSSFCell cell = rowHead.createCell((short) curColIndx); 
       cell.setCellStyle(headStyle); 
       cell.setCellValue(metaData.getColumnName(curColIndx + 1)); 
      } 
      int index = 1; 
      while (resultSet.next()) { 
       XSSFRow row = sheet.createRow((short) index); 

       for (int curColIndx = 0; curColIndx < colCount; curColIndx++) { 
        XSSFCell cell = row.createCell((short) curColIndx); 
        if (index % 2 == 1) { 
         cell.setCellStyle(oddStyle); 
        } 
        else { 
         cell.setCellStyle(evenStyle); 
        } 
        int type = metaData.getColumnType(curColIndx + 1); 
        if (type == Types.TIMESTAMP) { 
         cell.setCellValue(sdf.format(resultSet.getDate(curColIndx + 1))); 
        } else if (type == Types.VARCHAR || type == Types.CHAR) { 
         cell.setCellValue(resultSet.getString(curColIndx + 1)); 
        } else { 
         cell.setCellValue(resultSet.getLong(curColIndx + 1)); 
        } 
       } 

       index++; 
      } 
      baoStream = new ByteArrayOutputStream(); 
      try { 
//This Writes 27,842 bytes xlsx file to disk for sample data. 
       workbook.write(out); 
//same workbook is written to ByteArrayOutputStream() 
       workbook.write(baoStream); 
//But, baoStream size is 49022bytes and After Encryption and Zipping It Creates File of Size 43,084 bytes. 
       System.out.println("baoStream.size() :" + baoStream.size()); 
       try { 
        //byte[] bytesToWrite = getBytesFromFile(); 
        byte[] bytesToWrite = baoStream.toByteArray(); 
        InMemoryOutputStream inMemoryOutputStream = new InMemoryOutputStream(); 

        zos = new ZipOutputStream(inMemoryOutputStream); 

        ZipParameters parameters = new ZipParameters(); 
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); 
        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 
        parameters.setFileNameInZip(xlsxFileName); 
        parameters.setSourceExternalStream(true); 

        zos.putNextEntry(null, parameters); 
        zos.write(bytesToWrite); 
        zos.closeEntry(); 
        zos.finish(); 
        zos.close(); 

        // Write contents in our InMemoryOutputStream to a zip file to test if this worked 
        writeContentsToZipFile(inMemoryOutputStream); 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       out.close(); 
       resultSet.close(); 
       connection.close(); 
       System.out.println("Excel written successfully.."); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } catch (Exception e) { 
      System.out.println("Exception is :" + e.toString()); 
     } 
    } 

    public ZipCreationInMemory() { 
     //testZipCreationInMemory(); 
     createXlsxFile(); 
    } 


package zipconversion; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.util.ArrayList; 
import java.util.List; 

/** 
* Writes the content to memory. 
* 
*/ 
public class InMemoryOutputStream extends OutputStream { 

    // As we cannot know the size of the zip file that is being created, 
    // we cannot maintain a byte array. We will copy all the bytes that 
    // gets passed in the write() method to a List. Once all writing is done, 
    // we can create a byte array from this List and this will be the content 
    // of the zip file 
    private List byteList; 

    // flag to keep track if the outputstream is closed 
    // no further write operations should be performed once this stream is closed 
    private boolean closed; 

    public InMemoryOutputStream() { 
     byteList = new ArrayList(); 
     closed = false; 
    } 

    public void write(int b) throws IOException { 
     if (closed) { 
      throw new IOException("trying to write on a closed output stream"); 
     } 

     byteList.add(Integer.toString(b)); 
    } 

    public void write(byte[] b) throws IOException { 
     if (b == null) { 
      return; 
     } 
     write(b, 0, b.length); 
    } 

    public void write(byte[] b, int off, int len) throws IOException { 
     if (closed) { 
      throw new IOException("trying to write on a closed output stream"); 
     } 

     if (b != null && len > 0) { 
      for (int i = 0; i < len; i++) { 
       byteList.add(Byte.toString(b[i])); 
      } 
     } 
    } 

    public byte[] getZipContent() { 
     if (byteList.size() <= 0) { 
      return null; 
     } 

     byte[] zipContent = new byte[byteList.size()+1]; 

     for (int i = 0; i < byteList.size(); i++) { 
      zipContent[i] = Byte.parseByte((String) byteList.get(i)); 
     } 
      return zipContent; 
    } 

    public void close() throws IOException { 
     closed = true; 
    } 
} 
+3

왜이 전화를 부르시겠습니까? 'zos.putNextEntry (null, parameters);'zip에 null 항목을 추가하면 해당 도구가 손상된 항목에 대해 올바르게 경고합니다. –

+1

하나의 방법으로 너무 많은 일이 발생했습니다. 그것을 향상 시키십시오. –

+0

zos.putNextEntry (null, parameters); 압축 된 파일에 파일 이름을 추가합니다. – AVA

답변

0

버그 방법 writeContentsToZipFile(inMemoryOutputStream)에서 가능하지만, 당신은 효과가 아니라,

나는이 (가) 필요하지 않습니다 class InMemoryOutputStream의 구현 생각 ... 그것은 소스 코드의 게시물 더 많은 문제가 발생하지 않았다. 당신이 파일로 압축 내용을 저장하려는 경우 메모리에 우편 내용을 저장하려면

  • , ByteArrayInputStream inMemoryOutputStream = new ByteArrayInputStream(bytesToWrite.length);

참고로 교체, FileOutputStream

  • 로 교체 : 첫 번째 매개 변수를 zos.putNextEntry(null, parameters)의 값은 null입니다. parameters.setSourceExternalStream(true) 일 때 작동합니다. 이 모드에서는 파일 이름과 다른 매개 변수가 ZipParameters를 통해 제공됩니다.