Java实现一次性下载多个文件
目录
- 新增Excel工具类
- 具体业务代码
- 1、对数据预处理
- 2、按500条数据进行Excel文件生成
- 3、将存放Excel的文件夹压缩导出
- 总结
最近项目遇到一个需求,需要一次性导出全部数据,而且是按照500条数据一个文件。
话不多说,开始。
新增Excel工具类
可以直接复制
import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.util.CellRangeAddress; //关于下面这两个包,可以直接用Java自带的,也可以导入 //我这里是导入的,可以进行一个编码的设置,不过我是没有设置成功,反而乱码 //建议里面的文件名什么的都用英文,不用担心乱码,哈哈 import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; import java.io.*; import java.util.ArrayList; import java.util.List; public class ExportExcel { // 显示的导出表的标题 private String title; // 导出表的列名 private String[] rowName; private List<Object[]> dataList = new ArrayList<Object[]>(); public ExportExcel() { } // 构造函数,传入要导出的数据 public ExportExcel(String title, String[] rowName, List<Object[]> dataList) { this.dataList = dataList; this.rowName = rowName; this.title = title; } // 导出数据 public void export(OutputStream out) throws Exception { try { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(title); // 产生表格标题行 HSSFRow rowm = sheet.createRow(0); HSSFCell cellTitle = rowm.createCell(0); //sheet样式定义【】 HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); HSSFCellStyle style = this.getStyle(workbook); sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1))); cellTitle.setCellStyle(columnTopStyle); cellTitle.setCellValue(title); // 定义所需列数 int columnNum = rowName.length; HSSFRow rowRowName = sheet.createRow(2); // 将列头设置到sheet的单元格中 for (int n = 0; n < columnNum; n++) { HSSFCell cellRowName = rowRowName.createCell(n); cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); HSSFRichTextString text = new HSSFRichTextString(rowName[n]); cellRowName.setCellValue(text); cellRowName.setCellStyle(columnTopStyle); } // 将查询到的数据设置到sheet对应的单元格中 for (int i = 0; i < dataList.size(); i++) { Object[] obj = dataList.get(i);// 遍历每个对象 HSSFRow row = sheet.createRow(i + 3);// 创建所需的行数 for (int j = 0; j < obj.length; j++) { HSSFCell cell = null; //这几行被注释掉的代码,是给表格第一列进行一个赋值起一个编号的效果,不过我认为没必要 // if (j == 0) { // cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC); // cell.setCellValue(i + 1); // } else { cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING); if (!"".equals(obj[j]) && obj[j] != null) { cell.setCellValue(obj[j].toString()); } // } cell.setCellStyle(style); } } // 让列宽随着导出的列长自动适应 for (int colNum = 0; colNum < columnNum; colNum++) { int cphpolumnWidth = sheet.getColumnWidth(colNum) / 256; for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) { HSSFRow currentRow; if (sheet.getRow(rowNum) == null) { currentRow = sheet.createRow(rowNum); } else { currentRow = sheet.getRow(rowNum); } if (currentRow.getCell(colNum) != null) { HSSFCell currentCell = currentRow.getCell(colNum); if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) { int length = currentCell.getStringCellValue().getBytes().length; if (columnWidth < length) { columnWidth = length; } } } } if (colNum == 0) { sheet.setColumnWidth(colNum, (columnWidth - 2) * 256); } else { sheet.setColumnWidth(colNum, (columnWidth + 4) * 256); } } if (workbook != null) { try { workbook.write(out); } catch (Exception e) { e.printStackTrace(); } 编程客栈 } } catch (Exception e) { } } /** * 列头单元格样式 */ public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) { // 设置字体 HSSFFont font = workbook.createFont(); // 设置字体大小 font.setFontHeightInPoints((short) 11); // 字体加粗 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 设置字体名字 font.setFontName("Courier New"); // 设置样式 HSSFCellStyle style = workbook.createCellStyle(); // 设置低边框 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 设置低边框颜色 style.setBottomBorderColor(HSSFColor.BLACK.index); // 设置右边框 style.setBorderRight(HSSFCellStyle.BORDER_THIN); // 设置顶边框 style.setTopBorderColor(HSSFColor.BLACK.index); // 设置顶边框颜色 style.setTopBorderColor(HSSFColor.BLACK.index); // 在样式中应用设置的字体 style.setFont(font); // 设置自动换行 style.setWrapText(false); // 设置水平对齐的样式为居中对齐; style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return style; } public HSSFCellStyle getStyle(HSSFWorkbook workbook) { // 设置字体 HSSFFont font = workbook.createFont(); // 设置字体大小 font.sjsetFontHeightInPoints((short) 10); // 字体加粗 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 设置字体名字 font.setFontName("Courier New"); // 设置样式; HSSFCellStyle style = workbook.createCellStyle(); // 设置底边框; style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 设置底边框颜色; style.setBottomBorderColor(HSSFColor.BLACK.index); // 设置左边框; style.setBorderLeft(HSSFCellStyle.BORDER_THIN); javascript // 设置左边框颜色; style.setLeftBorderColor(HSSFColor.BLACK.index); // 设置右边框; style.setBorderRight(HSSFCellStyle.BORDER_THIN); // 设置右边框颜色; style.setRightBorderColor(HSSFColor.BLACK.index); // 设置顶边框; style.setBorderTop(HSSFCellStyle.BORDER_THIN); // 设置顶边框颜色; style.setTopBorderColor(HSSFColor.BLACK.index); // 在样式用应用设置的字体; style.setFont(font); // 设置自动换行; style.setWrapText(false); // 设置水平对齐的样式为居中对齐; style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 设置垂直对齐的样式为居中对齐; style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return style; } //压缩文件 public void ZipFiles(File[] srcfile, File zipfile) { ZipOutputStream out = null; byte[] buf = new byte[1024]; try { out = new ZipOutputStream(new FileOutputStream( zipfile)); // out.setEncoding("UTF-8"); for (int i = 0; i < srcfile.length; i++) { FileInputStream in = new FileInputStream(srcfile[i]); out.putNextEntry(new ZipEntry(srcfile[i].getName())); int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } out.closeEntry(); in.close(); } out.close(); } catch (IOException e) { e.printStackTrace(); } } /*** * 删除指定文件夹下所有文件 * * @param path 文件夹完整绝对路径 * @return */ public static boolean delAllFile(String path) { boolean flag = false; File file = new File(path); if (!file.exists()) { return flag; } if (!file.isDirectory()) { return flag; } String[] tempList = file.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if (path.endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { temp.delete(); } if (temp.isDirectory()) { delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件 flag = true; } } return flag; } }
具体业务代码
注:
1、对数据预处理
String title = "业主信息表";//这个是表格的标题,不是文件名 //每个单元格的标题,具体内容自己设置 String[] rowsName = {"业主id", "姓名","身份证号","楼栋号", "单元号", "楼层号", "房间号", "电话号码"}; //存放需要的数据 ArrayList<Object[]> dataList = new ArrayList<>(); Object[] objs = null; //根据业务需求,查询出要导出的数据 List<CitRoomMaster> list = citRoomMasterService.getList(); //将全部数据按需加载到dataList中 //对null值进行一个处理,因为如果是空的导入文件中会造成整个文件损坏,读取不到任何数据 for (CitRoomMaster c :list) { objs = new Object[rowsName.length]; objs[0] = c.getId(); objs[1] = c.getUsername() == null?"未录入":c.getUsername(); objs[2] = c.getIdCard() == null?"未录入":c.getIdCard(); objs[3] = c.getBuilding() == null?"未录入":c.getBuilding(); objs[4] = c.getUnit() == null?"未录入":c.getUnit(); objs[5] = c.getRoomLevel() == null?"未录入":c.getRoomLevel(); objs[6] = c.getRoomNum() == null?"未录入":c.getRoomNum(); objs[7] = c.getTel() == null?"未录入":c.getTel(); dataList.add(objs); }
2、按500条数据进行Excel文件生成
// 将excel导出的文件位置,临时文件,注意,一定是一个不存在的文件,因为后面会把这个文件夹删完 String filePath = "C:\\小区业主信息"+ File.separator; // 得到此路径下文件 File fileDir = new File(filePath); //创建文件夹 if (!fileDir.exists() && !fileDir.isDirectory()) { fileDir.mkdirs(); } // 用于存放生成的excel文件名称 List<www.devze.com;String> fileNames = new ArrayList<String>(); // 导出Excel文件的路径 String fullFilePath = ""; //输出流 FileOutputStream os = null; //拿到整个需要循环导出的次数 int length = list.size()%500 == 0 ? list.size()/500 : (list.size()/500)+1; for (int i = 0; i < length; i++) { //给文件命名。随机命名 自定义 String fileName = "OwnerInformation-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls"; //生成Excel文件导出的路径 fullFilePath = filePath + File.separator + fileName; fileNames.add(fullFilePath); os = new FileOutputStream(fullFilePath); //调用poi的工具类 int end = 0; //对list进行截取,每500条数据 ExportExcel ex = new ExportExcel(title, rowsName, dataList.subList(i*500,end = (i+1)*500<=list.size()?(i+1)*500:list.size())); try { ex.export(os); } catch (Exception e) { e.printStackTrace(); } os.flush(); os.close(); os = null; }
3、将存放Excel的文件夹压缩导出
就完成需求了
//告诉浏览器数据格式,将头和数据传到前台 String headStr = "attachment; filename=\"" + zip.getName() + "\""; response.setContentType("APPLICATION/zip"); // response.setHeader("Location",zip.getName()); response.setHeader("Content-Disposition", headStr); OutputStream out = response.getOutputStream(); InputStream in = new FileInputStream(zipFilePath); byte[] buffer = new byte[1024]; int i = -1; while ((i = in.read(buffer)) != -1) { out.write(buffer, 0, i); } out.flush(); out.close(); in.close(); out = null; try { excelUtil.delAllFile(filePath); // 删除完里面所有内容 filePath = filePath.toString(); java.io.File myFilePath = new java.io.File(filePath); myFilePath.delete(); // 删除空文件夹 } catch (Exception e) { e.printStackTrace(); }
最后再说一点:
- 还是关于中文乱码的问题,本来最开始的我是用的中文写文件名,并且在自己电脑上测试的时候是么有乱码的。
- 但是部署到公司服务器上,就乱码了,怀疑是编码不一致问题导致的,因为时间问题,也没有去调试了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论