需求:把数据库数据,每500条装进一个excel,输出的是所有excel压缩后的zip压缩包。
这里实现的思路是,先查数据库有多少条记录,然后计算500条有多少页,再使用分页查询的方式,每500条将数据从数据库查出,创建好excel文件,将数据循环写入excel,然后输出到临时文件夹。循环将所有数据分别输出到excel中后,再读取临时目录,将目录压缩成zip,接着把临时文件夹删除,然后把zip响应给前端,至此浏览器上可以查看下载成功的zip文件
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSON;
import com.richwit.model.InvoiceReceipt;
import com.richwit.service.BaseService;
import com.richwit.util.LogTool;
import com.richwit.util.Request;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @version 1.0
*/
public class importExcelAction {
private static final int BUFFER_SIZE = 2 * 1024;
@Autowired
private BaseService baseService;
@Action("newImportInvoiceReceipt")
public String newImportInvoiceReceipt() {
String importDate = Request.getParameter("importDate");
Map<String,Object> map = new HashMap<>();
String sql = "select * from InvoiceReceipt where importDate=:importDate";
map.put("importDate", importDate);
@SuppressWarnings("unchecked")
List<InvoiceReceipt> invoiceReceiptList = baseService.listBySql(sql, map,InvoiceReceipt.class);
@SuppressWarnings("rawtypes")
List<Map> invoiceReceiptLists = null;
HSSFWorkbook workbook = null;
HSSFSheet sheet = null;
if(invoiceReceiptList.size() > 0) {
System.out.println("有数据");
//生成Excel
File fileExcel =new File("D://"+"Excel");
//如果文件夹存在则删除
if (fileExcel.exists() && fileExcel.isDirectory()) {
deleteDirectory(fileExcel);
}
fileExcel.mkdir();
int num = invoiceReceiptList.size()/500;
int page = 0;
int rows = 500;
for(int j = 0;j<(num+1);j++) {
workbook = new HSSFWorkbook();
File file = new File("D://"+"Excel"+"/template"+j+".xls");
FileOutputStream fileOutputStream=null;
try {
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
page++;
invoiceReceiptLists = baseService.listBySql(sql, map,page,rows);
sheet = workbook.createSheet("Sheet0");
sheet.setColumnWidth(0, 3500);
sheet.setColumnWidth(1, 3500);
sheet.setColumnWidth(2, 3000);
sheet.setColumnWidth(3, 3000);
HSSFRow row = sheet.createRow(0);
row.createCell(0).setCellValue("*发票代码");
row.createCell(1).setCellValue("*发票号码");
row.createCell(2).setCellValue("*开票日期");
row.createCell(3).setCellValue("税额");
int i = 0;
for(Map maps:invoiceReceiptLists) {
Row contentRow = sheet.createRow(i+1);
InvoiceReceipt invoiceReceipt = JSON.parseObject(JSON.toJSONString(maps), InvoiceReceipt.class);
contentRow.createCell(0).setCellValue(invoiceReceipt.getFpdm());
contentRow.createCell(1).setCellValue(invoiceReceipt.getFphm());
contentRow.createCell(2).setCellValue(invoiceReceipt.getImportDate());
if(invoiceReceipt.getTotaltax() !=null) {
contentRow.createCell(3).setCellValue(invoiceReceipt.getTotaltax());
}
i++;
}
workbook.setActiveSheet(0);
try {
workbook.write(fileOutputStream);
fileOutputStream.close();
} catch (Exception e) {
}
}
}
FileOutputStream fos;
HttpServletResponse response=ServletActionContext.getResponse();
/** .设置response的header */
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=excel.zip");
/** .调用工具类,下载zip压缩包 */
// 这里我们不需要保留目录结构
try {
toZip("D:\\Excel", response.getOutputStream(), false);
} catch (IOException e) {
e.printStackTrace();
}
map.put("msg", "导出成功!");
Request.setAttribute("data", JSON.toJSONString(map));
return null;
}
public static void deleteDirectory(File file){
if(file.isFile()){
file.delete();//清理文件
}else{
File list[] = file.listFiles();
if(list!=null){
for(File f: list){
deleteDirectory(f);
}
file.delete();//清理目录
}
}
}
public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException{
long start = System.currentTimeMillis();
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
File sourceFile = new File(srcDir);
compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 压缩成ZIP 方法
* @param srcFiles 需要压缩的文件列表
* @param out 压缩文件输出流
* @throws RuntimeException 压缩失败会抛出运行时异常
*/
public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
long start = System.currentTimeMillis();
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
for (File srcFile : srcFiles) {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int len;
FileInputStream in = new FileInputStream(srcFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 递归压缩方法
* @param sourceFile 源文件
* @param zos zip输出流
* @param name 压缩后的名称
* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
* @throws Exception
*/
private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception{
byte[] buf = new byte[BUFFER_SIZE];
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);
}
}
}
}
}
}