Java 从内存文件在磁盘上创建Zip文件

Java 从内存文件在磁盘上创建Zip文件,java,apache-poi,zip4j,Java,Apache Poi,Zip4j,首先,请原谅我糟糕的编码 要求: 1.从数据库结果集在内存中创建xls/xlsx报告(即,不应将纯文本文件写入磁盘)。 2.从内存中的xlsx文件在磁盘上创建ZIP 环境: WinXP SP2、JDK1.6_06、Zip4j1.3.1、poi3.8 我正在使用Apache的POI和Zip4j,并遵循Shrikant先生在“”上发布的示例 观察结果: 1.该程序将27842字节的xlsx文件写入磁盘以获取样本数据。 2.同一工作簿创建ByteArrayOutputStream,其大小为49022字

首先,请原谅我糟糕的编码

要求:
1.从数据库结果集在内存中创建xls/xlsx报告(即,不应将纯文本文件写入磁盘)。
2.从内存中的xlsx文件在磁盘上创建ZIP

环境:
WinXP SP2、JDK1.6_06、Zip4j1.3.1、poi3.8

我正在使用Apache的POI和Zip4j,并遵循Shrikant先生在“”上发布的示例

观察结果:
1.该程序将27842字节的xlsx文件写入磁盘以获取样本数据。
2.同一工作簿创建ByteArrayOutputStream,其大小为49022字节
3.加密和压缩后,它将创建大小为43084字节的文件。
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;
    }
}
package-zipconversion;
导入java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.ResultSet;
导入java.sql.ResultSetMetaData;
导入java.sql.Statement;
导入java.sql.Types;
导入java.text.simpleDataFormat;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.List;
导入java.util.Random;
导入net.lingala.zip4j.io.ZipOutputStream;
导入net.lingala.zip4j.model.zip参数;
导入net.lingala.zip4j.util.Zip4jConstants;
导入org.apache.poi.ss.usermodel.CellStyle;
导入org.apache.poi.xssf.usermodel.XSSFCell;
导入org.apache.poi.xssf.usermodel.XSSFCellStyle;
导入org.apache.poi.xssf.usermodel.XSSFColor;
导入org.apache.poi.xssf.usermodel.xssfont;
导入org.apache.poi.xssf.usermodel.XSSFRow;
导入org.apache.poi.xssf.usermodel.xssfheet;
导入org.apache.poi.xssf.usermodel.xssf工作簿;
公共类ZipCreationInMemory{
ZipOutputStream zos=null;
XSSF工作簿=空;
ByteArrayOutputStream=null;
字符串路径=null;
字符串xlsxfileExtn=null;
字符串zipfilextn=null;
仅限字符串filename=null;
字符串xlsxFileName=null;
字符串zipFileName=null;
字符串xlsxFilePath=null;
字符串zipFilePath=null;
公共静态整数和整数(整数最小值,整数最大值){
Random rand=新的Random();
int randomNum=rand.nextInt((最大-最小)+1)+min;
返回随机数;
}
public void createXlsxFile(){
试一试{
SimpleDateFormat timeFormat=新的SimpleDateFormat(“hh_mm_ss”);
path=“D:\\abcd\\”;
xlsxfileExtn=“.xlsx”;
zipfileExtn=“.zip”;
onlyFileName=“ReportData”。concat(timeFormat.format(new Date());
xlsxFileName=onlyFileName+xlsxfileExtn;
zipFileName=仅文件名+zipfileExtn;
xlsxFilePath=path+xlsxFileName;
zipFilePath=路径+zipFileName;
FileOutputStream out=新的FileOutputStream(新文件(xlsxFilePath));
工作簿=新XSSFWorkbook();
XSSFSheet sheet=workbook.createSheet(“报告”);
XSSFRow rowHead=sheet.createRow((短)0);
XSSFCellStyle headStyle=工作簿.createCellStyle();
XSSFFont headerFont=workbook.createFont();
headerFont.setBold(真);
setColor(新的XSSFColor(新的java.awt.Color(255,0,0));
headStyle.setFont(headerFont);
setFillForegroundColor(新的XSSFColor(新的java.awt.Color(255,255));
头部样式。设置填充图案(单元样式。立体前景);
XSSFCellStyle oddStyle=工作簿.createCellStyle();
setFillForegroundColor(新的XSSFColor(新的java.awt.Color(randInt(125255)、randInt(125255)、randInt(125255)));
oddStyle.setFillPattern(CellStyle.SOLID\u前景);
//JDBC配置
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);
语句st=connection.createStatement();
ResultSet ResultSet=st.executeQuery(“从表_名称中选择*);
ResultSetMetaData元数据=resultSet.getMetaData();
int colCount=metaData.getColumnCount();
SimpleDataFormat sdf=新的SimpleDataFormat(“dd-MMM-yyy-hh:mm:ss”);
对于(int-curColIndx=0;curColIndx