网上有许多java生成zip的代码,但有很多代码在其实是有问题的,还有和我的需求不符的,下面是各种我的代码和之前试过的代码和它们的问题的一个记录
1.生成excel部分的代码和对打包zip接口的调用
long startTime = System.currentTimeMillis();
int isExportFinish = 0;
String fdsId ="";
String zipName="";
try {
//查询总数
int aloneFileNum = 50000; //一个文件最大条数
List<String> listFiles = new ArrayList<>();
int fileNum = allAcountNum / aloneFileNum + 1; // 取整
final String foldPath = medicalProperties.getFileUploadPath() + DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS") +
(new SecureRandom().nextInt(1000));
File folder=new File(foldPath);
boolean success = folder.mkdir();
String exportType = "EXCEL";
String title = "";
String jasperFileName = "";
title = "职工缴费统计表";
jasperFileName = "zgjftjb.jasper";
String filePath =medicalProperties.getFileUploadPath();
List<List<TPaymentPutDetails>>lists =new ArrayList<>();
if(list.size()>50000){
lists= Lists.partition(list,50000);
}else{
lists.add(list);
}
for(int i = 0; i < fileNum; i++){
List<TPaymentPutDetails> listExcel = lists.get(i);
Map<String, Object> parameters = new HashMap<String, Object>();
String fileName = new String(title);
String[] sheetName = { title };
parameters.put("title", title);
JRDataSource dataSource = new JRBeanCollectionDataSource(listExcel);
String excelName=ExportUtil.getInstance().exportExcel(filePath,foldPath,jasperFileName, parameters, dataSource, sheetName, fileName);
//导出数据,生成excel文件,返回文件路径
List<String> listFilePath = new ArrayList<>();
// listFilePath.add(foldPath+"\\" +excelName);
listFiles.add(foldPath+File.separator +excelName);
}
try{
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.OTHERS_READ);
Path path = Paths.get(folder.getAbsolutePath());
Files.setPosixFilePermissions(path, perms);
zipName="职工缴费统计导出"+DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS")+ ".zip";
//生成zip文件
// String zipFileName = "D:\\file\\error\\会员导出"+ DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS") + ".zip";
String zipFileAddr = filePath+File.separator +zipName;
// fdsId=fileToZipNew(foldPath,listFiles, zipFileAddr,zipName);
fdsId = fileToZipNew(foldPath,listFiles, zipFileAddr,zipName);
}catch (IOException e){
logger.error("生成zip失败:"+e.getMessage());
}
a10BaseExportRecord.setFileName(zipName);
a10BaseExportRecord.setRemark("导出成功");
isExportFinish = 1;
} catch (Exception e) {
logger.error("", e);
a10BaseExportRecord.setRemark("服务中断");
isExportFinish = 3;
} finally {
a10BaseExportRecord.setIsSuccess(isExportFinish);
a10BaseExportRecord.setId(id);
a10BaseExportRecord.setUpdateTime(com.pass.service.common.util.DateUtil.getTime());
if(isExportFinish==1){
a10BaseExportRecord.setFileUrl(fdsPort+fdsId);
a10BaseExportRecord.setFileValid(1);
}else{
a10BaseExportRecord.setFileValid(2);
}
tbExportMapper.updateById(a10BaseExportRecord);
long endTime = System.currentTimeMillis();
logger.info("导出时间秒:{}", (endTime - startTime) / 1000);
}
}
2.调用打包工具类和处理临时文件的代码
public String fileToZipNew(String sourceDir, List<String> pathList,String zipFileAddr, String zipFileName) throws IOException {
String fstdfsFileId = "";
File zipF=null;
try {
FileZip.zip(sourceDir, zipFileAddr);
zipF=new File(zipFileAddr);
fstdfsFileId = FastDFSClientUtils.upload(zipF,zipFileName);
}catch (Exception e){
logger.error("上传zip到fds失败"+e.getMessage());
}finally {
if(zipF.exists()){
zipF.delete();
}
File file =new File(sourceDir);
if(file.isDirectory()){
String[] fileList =file.list();
if(null!=fileList){
for(String fileName:fileList){
File excelFile =new File(sourceDir+File.separator+fileName);
excelFile.delete();
}
file.delete();
}
}
}
return fstdfsFileId;
}
3.最重要的工具类的代码
package com.pass.service.medical.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 说明:java压缩成zip
* 作者:FH Admin Q 3 1359679 0
* 官网:www.fhadmin.org
*/
public class FileZip {
/**
* @param inputFileName 你要压缩的文件夹(整个完整路径)
* @param zipFileName 压缩后的文件(整个完整路径)
* @throws Exception
*/
public static Boolean zip(String inputFileName, String zipFileName) throws Exception {
File zip=new File(inputFileName);
zip(zipFileName, zip,zip.getName());
return true;
}
private static void zip(String zipFileName, File inputFile,String zipName) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
// zip(out, inputFile, "");
compress(inputFile,out,zipName,false);
out.flush();
out.close();
}
private static void zip(ZipOutputStream out, File f, String base) throws Exception {
if (f.isDirectory()) {
File[] fl = f.listFiles();
// out.putNextEntry(new ZipEntry(base + File.separator));
base = base.length() == 0 ? "" : base + File.separator;
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + fl[i].getAbsolutePath());
}
} else {
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
in.close();
}
}
private static void compress(File sourceFile, ZipOutputStream zos, String name,
boolean KeepDirStructure) throws Exception {
byte[] buf = new byte[2048];
if (sourceFile.isFile()) {
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if (listFiles == null || listFiles.length == 0) {
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if (KeepDirStructure) {
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
} else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
} else {
compress(file, zos, file.getName(), KeepDirStructure);
}
}
}
}
}
public static void main(String [] temp){
try {
zip("E:\\images\\yqmedical\\20240904092558853343","E:\\images\\yqmedical\\职工缴费统计导出20240904092558853343.zip");//你要压缩的文件夹 和 压缩后的文件
}catch (Exception ex) {
ex.printStackTrace();
}
}
}
其中private static void zip(ZipOutputStream out, File f, String base) throws Exception 也是一种打包方式,但这种打包方式会将路径上的所有文件夹都包含在内将服务器上临时文件的全路径暴露出来,所以后来博主换了compress接口并将KeepDirStructure写死传入false,但这个方法其实可以按需求决定是否打包上层路径
3.一种有问题的打包方式:这种打包方式生成的zip包无法解压提示文件损坏
private static void zipFile(String path, String sourceFile, ZipOutputStream zos) throws IOException {
File file =new File(sourceFile);
if(file.isDirectory()){
String[] fileList =file.list();
if(null!=fileList){
for(String fileName:fileList){
zipFile(path,sourceFile+File.separator+fileName,zos);
}
}
return;
}else{
try (FileInputStream fis = new FileInputStream(sourceFile)) {
ZipEntry z=new ZipEntry(sourceFile);//压缩文件各文件的文件名在此设置。
zos.putNextEntry(z);
byte[] b =new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1) {
zos.write(b,0,len);
}
fis.close();
}
}
}