文章目录

  • 基本概念
  • 导入依赖
  • 操作示例
  • 操作Execl工具类
  • 如何手动撸一个execl文件导出
  • Controller层代码
  • 尾语

基本概念

java操纵excel文件常用的有jxl和poi两种方式,jxl不支持.xlsx,而poi支持.xlsx。本文主要介绍poi方式。

Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS Office文档进行解码。

poi一般常用的有HSSFWorkbookXSSFWorkbook两个实现类。

HSSFWorkbook是针对.xls文件,这种方式导出的文件格式为office 2003专用格式,优点是导出数据速度快,但是最多65536行数据

XSSFWorkbook是针对.xslx文件,这种方式导出的文件格式为office 2007专用格式,即.xlsx,优点是导出的数据不受行数限制,缺点导出速度慢

内置其他的api:

HSSF : 读写 Microsoft Excel XLS 格式文档
XSSF  : 读写 Microsoft Excel OOXML XLSX 格式文档
SXSSF : 读写 Microsoft Excel OOXML XLSX 格式文档
HWPF : 读写 Microsoft Word DOC 格式文档
HSLF  : 读写 Microsoft PowerPoint 格式文档
HDGF : 读 Microsoft Visio 格式文档
HPBF : 读 Microsoft Publisher 格式文档
HSMF : 读 Microsoft Outlook 格式文档

导入依赖

<!--poi-->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version>
</dependency>

操作示例

//1.创建Excel对象
XSSFWorkbook wb = new XSSFWorkbook();
HSSFWorkbook wb = new HSSFWorkbook();
//2.创建Sheet对象
Sheet sheet = wb.createSheet();Row createRow(int rownum);// 创建行
Row getRow(int rownum);// 获取行
int getPhysicalNumberOfRows();// 获取工作单行数
int addMergedRegion(CellRangeAddress region);// 设置合并单元格范围
void autoSizeColumn(int column);// 设置默认单元格列宽
void setColumnWidth(int columnIndex, int width);// 设置单元格列宽(1/256)
void setDefaultRowHeightInPoints(float height);// 设置默认单元格行高//3.创建行对象(索引从0开始)
Row nRow = sheet.createRow(0);
//4.设置行高和列宽
nRow.setHeightInPoints(26.25f);
sheet.setColumnWidth(1,26*256); //(列的索引,列宽*256(理解为固定写法))
//5.创建单元格对象(索引从0开始)
Cell nCell = nRow.createCell(0);
//6.设置单元格内容
nCell.setCellValue("dinTalk");void setCellValue(RichTextString value);// 设置富文本
void setCellFormula(String formula) throws FormulaParseException;// 设置公式
void setCellType(CellType cellType);// 设置单元格类型 _NONE NUMERIC STRING FORMULA BLANK BOOLEAN ERROR
String getStringCellValue();
double getNumericCellValue();// 获取数值类型
String getCellFormula();// 获取公式//7.创建单元格样式对象
CellStyle style = wb.createCellStyle();
//8.创建字体对象
Font font = wb.createFont();
//9.设置字体和其大小及效果
font.setFontName("黑体");
font.setFontHeightInPoints((short)12);
font.setBold(true); //加粗
//10.设置样式
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);    //横向居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//纵向居中
style.setBorderTop(BorderStyle.THIN);        //上细线
style.setBorderBottom(BorderStyle.THIN);      //下细线
style.setBorderLeft(BorderStyle.THIN);        //左细线
style.setBorderRight(BorderStyle.THIN);        //右细线void setFontName(String name);// 设置字体名称
public void setBold(boolean bold);// 设置是否加粗
void setFontHeightInPoints(short height);// 设置字体大小 //11.为单元格应用样式
nCell.setCellStyle(style);
//12. Workbook
Sheet createSheet();// 创建表单
Sheet createSheet(String sheetname);
Sheet getSheetAt(int index);// 获取表单
Sheet getSheet(String name);
CellStyle createCellStyle();// 创建单元格样式
Font createFont();// 创建字体
void write(OutputStream stream);// 写入输出流
void close();// 关闭
13. 合并单元格rangeAdd = new CellRangeAddress(0, 6, 0, 0);
sheet.addMergedRegion(rangeAdd);
//设置合并单元格的边框
RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);//下细线
RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);
RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);
RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);

操作Execl工具类

ExcelExportServiceForZxfjkc.java:


/*** @author 小牛* @Time 2021-07-20* @Description:解析excel工具类*/@Service
public class ExcelExportServiceForZxfjkc {@Autowiredprivate TpDmGyGjService tpDmGyGjService;private static Logger logger = LoggerFactory.getLogger(ExcelExportServiceForPartenrs.class);/*** 将数据流写入到文件中** @param filename    为单个excel的路径和excel的名称,* @param inputStream inputStream就是获取的list数据流* @return* @author zhangjun*/public static int execute(String filename, InputStream inputStream) {logger.info("开始进行数据解析...");int success = 1;FileOutputStream outStream = null;try {File blobFile = new File(filename);File fileParent = blobFile.getParentFile();if(!fileParent.exists()){fileParent.mkdirs();}blobFile.createNewFile();outStream = new FileOutputStream(blobFile);byte[] buffer = new byte[2048];while ((inputStream.read(buffer)) != -1) {outStream.write(buffer);}outStream.flush();} catch (Exception e) {logger.error(e.getMessage(), e);success = 0;} finally {if (outStream != null) {try {outStream.close();} catch (IOException e) {e.printStackTrace();}}logger.info("ExcelExportServiceForZxfjkc.execute info={}","解析数据(数据转成文件)完成...");return success;}}//获取代码 对应的 证件类型public String getZzlxName(int dm) {//居民身份证 201// 中国护照227// 港澳居民来往内地通行证210// 港澳居民居住证 237// 台湾居民来往大陆通行证213// 台湾居民居住证 238// 外国护照208// 外国人永久居住证233// 外国人工作许可证(A类)239// 外国人工作许可证(B类)240// 外国人工作许可证(C类)241String zzlx="";switch (dm) {case 201:zzlx= "居民身份证";break;case 227:zzlx= "中国护照";break;case 210:zzlx= "港澳居民来往内地通行证";break;case 237:zzlx = "港澳居民居住证";break;case 213:zzlx = "台湾居民来往大陆通行证";break;case 238:zzlx = "台湾居民居住证";break;case 208:zzlx = "外国护照";break;case 233:zzlx = "外国人永久居住证";break;case 239:zzlx = "外国人工作许可证(A类)";break;case 240:zzlx = "外国人工作许可证(B类)";break;case 241:zzlx = "外国人工作许可证(C类)";break;default:zzlx = "未知证件代码,请核实";}return zzlx;}/*** 将多个Excel打包成zip文件** @param srcFile 该路径下的所有需要打成Zip的文件* @param zipFile 压缩的Zip文件* @author zhangjun*/public static void zipFiles(List<File> srcFile, File zipFile) {byte[] buf = new byte[1024];try {// 创建压缩文件 Create the ZIP fileZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));// 打包该文件夹下的所有文件 Compress the filesint size = srcFile.size();logger.info("ExcelExportServiceForZxfjkc.zipFiles info={}","该临时目录下共有:"+size+"文件!");int num =1;for (int i = 0; i < size; i++) {logger.info("ExcelExportServiceForZxfjkc.zipFiles info={}","开始压缩第:"+num+"文件...");File file = srcFile.get(i);FileInputStream in = new FileInputStream(file);// 将Zip文件添加到输出流中 Add ZIP entry to output stream.out.putNextEntry(new ZipEntry(file.getName()));// 将输出流安装字节流的形式读取到Zip压缩文件中 Transfer bytes from the file to the ZIP fileint len;while ((len = in.read(buf)) > 0) {out.write(buf, 0, len);}// Complete the entryout.closeEntry();in.close();num++;}logger.info("ExcelExportServiceForZxfjkc.zipFiles info={}","第"+size+"个文件压缩成功..全部文件压缩完成!");// Complete the ZIP fileout.close();} catch (IOException e) {logger.info("ExcelExportServiceForZxfjkc.zipFiles info={}","压缩文件出现异常...");logger.error(e.getMessage(), e);}}/*** 删除目录下所有的文件;* @param file 服务器目录地址 例如:* @author zhangjun*/public static boolean deleteExcelPath(File file) {logger.info("ExcelExportServiceForZxfjkc.deleteExcelPath info={}","开始删除临时目录中的文件...");if (file.isDirectory()) {logger.info("ExcelExportServiceForZxfjkc.deleteExcelPath info={}","该文件属于文件夹,优先删除文件夹下的文件");String[] children = file.list();int length = children.length;//递归删除目录中的子目录下int number= 1;for (int i = 0; i < length; i++) {boolean success = deleteExcelPath(new File(file, children[i]));if (!success) {return false;}System.out.println("临时目录及文件删除成功...");logger.info("ExcelExportServiceForZxfjkc.deleteExcelPath info={}","删除第"+number+"文件");number++;}}// 目录此时为空,可以删除return file.delete();}/***  将Zip文件向浏览器发起是否下载请求* @param response 响应* @param serverPath 服务器路径* @param str Zip文件名* @author zhangjun*/public static void downFile(HttpServletResponse response, String serverPath, String str) {try {String path = serverPath + str;logger.info("ExcelExportServiceForZxfjkc.downFile info={}","临时文件目录为:"+path);File file = new File(path);logger.info("ExcelExportServiceForZxfjkc.downFile info={}","判断file.exists():"+true+"的话,将发起下载请求...");if (file.exists()) {logger.info("ExcelExportServiceForZxfjkc.downFile info={}","开始向浏览器发起下载请求...");InputStream ins = new FileInputStream(path);// 放到缓冲流里面BufferedInputStream bins = new BufferedInputStream(ins);// 获取文件输出IO流OutputStream outs = response.getOutputStream();BufferedOutputStream bouts = new BufferedOutputStream(outs);// 设置response内容的类型response.setContentType("application/octet-stream");// 设置头部信息response.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(str, "UTF-8"));int bytesRead = 0;byte[] buffer = new byte[1024];//开始向网络传输文件流while ((bytesRead = bins.read(buffer)) != -1) {bouts.write(buffer);}// 这里一定要调用flush()方法bouts.flush();response.flushBuffer();ins.close();bins.close();outs.close();bouts.close();} else {logger.info("ExcelExportServiceForZxfjkc.downFile info={}","判断file.exists():"+false);//response.sendRedirect("/admin/login");}} catch (IOException e) {logger.info("ExcelExportServiceForZxfjkc.downFile info={}","向浏览器发起下载请求异常...");logger.error(e.getMessage(), e);} finally {logger.info("ExcelExportServiceForZxfjkc.downFile info={}","下载请求发出以后,执行删除临时目录及文件...");File files = new File(serverPath);//删除临时目录deleteExcelPath(files);logger.info("ExcelExportServiceForZxfjkc.downFile info={}","临时目录删除功能结束!");}}}

如何手动撸一个execl文件导出

虽然省略了大量code,但可以参考具体的操作,比如样式怎么操作的

// 将数据导出至execl中public byte[] exportExcelForBZYS(TpZxfjkcZnjyzb data_znjy, TpZxfjkcJxjyzb data_jxjy, TpZxfjkcZfdkzczb data_zfdk,TpZxfjkcZfzjzczb data_zfzj, TpZxfjkcSylrzb data_sylr, String title,String qymc, String qynbm) throws Exception {byte[] bs = null;SXSSFWorkbook workbook = new SXSSFWorkbook();Sheet sheet = workbook.createSheet("V1.6");sheet.setDefaultColumnWidth((short) 20);//sheet.setDefaultRowHeightInPoints((short) 15.625 * 2);Row row = null;Cell cell = null;
/*        if (data_znjy == null) {throw new Exception("数据不能为空!");}*/int rowIndex = 1;// 标题Font titleFont = workbook.createFont();titleFont.setBold(true);//加粗titleFont.setColor(IndexedColors.BLACK.getIndex());titleFont.setFontHeightInPoints((short) 20);// 副标题Font subtitleFont = workbook.createFont();titleFont.setBold(true);//加粗titleFont.setColor(IndexedColors.BLACK.getIndex());titleFont.setFontHeightInPoints((short) 15);//标题的样式CellStyle titleCellStyle = workbook.createCellStyle();titleCellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中titleCellStyle.setFont(titleFont);titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);titleCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());//副标题的样式CellStyle tsubitleCellStyle = workbook.createCellStyle();tsubitleCellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中tsubitleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中tsubitleCellStyle.setFont(subtitleFont);tsubitleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);tsubitleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//带背景单元的样式CellStyle CellWithBackgroundStyle = workbook.createCellStyle();CellWithBackgroundStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中CellWithBackgroundStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中CellWithBackgroundStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);CellWithBackgroundStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());CellWithBackgroundStyle.setBorderLeft(BorderStyle.THIN);CellWithBackgroundStyle.setBorderBottom(BorderStyle.THIN);CellWithBackgroundStyle.setBorderRight(BorderStyle.THIN);CellWithBackgroundStyle.setBorderTop(BorderStyle.THIN);//带背景单元的样式 白色背景+边框CellStyle CellStyleWithWhiteBorder = workbook.createCellStyle();CellStyleWithWhiteBorder.setAlignment(HorizontalAlignment.CENTER);CellStyleWithWhiteBorder.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中CellStyleWithWhiteBorder.setFillPattern(FillPatternType.SOLID_FOREGROUND);CellStyleWithWhiteBorder.setFillForegroundColor(IndexedColors.WHITE.getIndex());CellStyleWithWhiteBorder.setBorderLeft(BorderStyle.THIN);CellStyleWithWhiteBorder.setBorderBottom(BorderStyle.THIN);CellStyleWithWhiteBorder.setBorderRight(BorderStyle.THIN);CellStyleWithWhiteBorder.setBorderTop(BorderStyle.THIN);//标题row = sheet.createRow(rowIndex++);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(0);cell.setCellStyle(titleCellStyle);cell.setCellValue(title);//标题cell.setCellStyle(titleCellStyle);CellRangeAddress rangeAdd = new CellRangeAddress(1, 1, 0, 6);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);row = sheet.createRow(rowIndex++);row.setHeightInPoints((short) 25);cell = row.createCell(0);cell.setCellValue("填报日期:");//------cell = row.createCell(4);cell.setCellValue("扣除年度:");cell = row.createCell(5);if(data_znjy != null) {cell.setCellValue(data_znjy.getBsnd());}else {cell.setCellValue("");}row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 25);cell = row.createCell(0);cell.setCellValue("纳税人姓名:");cell = row.createCell(1);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getXm());}else {cell.setCellValue("");}cell = row.createCell(4);cell.setCellValue("纳税人识别号:");cell = row.createCell(5);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getZzhm());//即身份证号码}else {cell.setCellValue("");}//======================rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(0);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("纳税人信息");rangeAdd = new CellRangeAddress(rowIndex, rowIndex+2, 0, 0);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);cell = row.createCell(1);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("证件类型");cell = row.createCell(2);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getZzlxStr());}else {cell.setCellValue("");}rangeAdd = new CellRangeAddress(rowIndex, rowIndex, 2, 4);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);cell = row.createCell(5);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("");cell = row.createCell(6);cell.setCellStyle(CellStyleWithWhiteBorder);cell.setCellValue("");//todo//-----------------------------rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(1);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("证件号码");cell = row.createCell(2);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getZzhm());}else {cell.setCellValue("");}rangeAdd = new CellRangeAddress(rowIndex, rowIndex, 2, 4);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);cell = row.createCell(5);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("电子邮箱");cell = row.createCell(6);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getDzyx());}else {cell.setCellValue("");}//--------------------------------------rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(1);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("联系地址");cell = row.createCell(2);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getNsrjcxxzb().getLxdz());}else {cell.setCellValue("");}rangeAdd = new CellRangeAddress(rowIndex, rowIndex, 2, 4);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);cell = row.createCell(5);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("配偶情况");cell = row.createCell(6);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getHaspo() == 1 ? "有配偶":"没有配偶");}else {cell.setCellValue("");}//------------------------------------rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(0);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("纳税人配偶信息");cell = row.createCell(1);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("姓名");cell = row.createCell(2);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getPoxm());}else {cell.setCellValue("");}cell = row.createCell(3);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("身份证件类型");cell = row.createCell(4);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(getZzlxName(data_znjy.getPozzlx()));}else {cell.setCellValue("");}cell = row.createCell(5);cell.setCellStyle(CellWithBackgroundStyle);cell.setCellValue("身份证件号码");cell = row.createCell(6);cell.setCellStyle(CellStyleWithWhiteBorder);if(data_znjy != null) {cell.setCellValue(data_znjy.getPozzhm());}else {cell.setCellValue("");}rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(0);cell.setCellStyle(tsubitleCellStyle);cell.setCellValue("一、子女教育支出扣除信息");//副标题 Subtitle 1rangeAdd = new CellRangeAddress(rowIndex, rowIndex, 0, 6);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);//-------------------------rowIndex++;row = sheet.createRow(rowIndex);row.setHeightInPoints((short) 15.625 * 2);cell = row.createCell(0);cell.setCellStyle(CellStyleWithWhiteBorder);cell.setCellValue("较上次报送信息是否发生变化:  □首次报送(请填写全部信息)     □无变化(不需重新填写)     □有变化(请填写发生变化的信息)");rangeAdd = new CellRangeAddress(rowIndex, rowIndex, 0, 6);sheet.addMergedRegion(rangeAdd);//设置合并单元格的边框RegionUtil.setBorderBottom(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderLeft(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderRight(BorderStyle.THIN,rangeAdd,sheet);RegionUtil.setBorderTop(BorderStyle.THIN,rangeAdd,sheet);if(data_znjy != null) {for(int i=0;i<data_znjy.getMxList().size();i++) {int index = addCellListZNJY(workbook,sheet,rowIndex, data_znjy.getMxList().get(i),i+1);rowIndex = index;}}//============================================================================= 省略ByteArrayOutputStream baos = new ByteArrayOutputStream();workBook.write(baos);Byte[ ] bs = baos.toByteArray();//bs = ExcelUtil.Excel2Bytes(workbook);return bs;}

Controller层代码

@RequestMapping(value = "/zxfjkc/export", method = RequestMethod.GET)public String zxfjkcExport(HttpSession session, HttpServletRequest request, HttpServletResponse response,RedirectAttributes attr) throws Exception {String dcmbys = request.getParameter("dcmbys");Map<String, Object> info = new HashMap<>();//声明一个集合,用来存放多个Excel文件路径及名称List<File> srcFile = new ArrayList<>();String qymc = tpQyxxQyxxService.selectByQynbm((String) info.get("qynbm")).getQymc();try {//获取数据List<TpJygzNsrjcxxzb> nsrList =  nsrjcxxzbService.selectByQynbm((String) info.get("qynbm"));String path = Thread.currentThread().getContextClassLoader().getResource("").toString().replace("classes/", "").replace("file:/","") + "tempZxfjkc/" ;//导出execl前,先删除旧的 文件夹File file_old = new File(path);if(file_old.exists()){excelExportServiceForZxfjkc.deleteExcelPath(file_old);}for(TpJygzNsrjcxxzb nsr : nsrList) {info.put("nsrid",nsr.getNsrid());TpZxfjkcZnjyzb mx_znjy = znjyService.getZnjyMx(info);//获取明细信息TpZxfjkcJxjyzb mx_jxjy = jxjyzbService.queryMx(info);TpZxfjkcZfdkzczb mx_zfdk = zfdkService.queryMx(info);TpZxfjkcZfzjzczb mx_zfzj = zfzjzczbService.queryMx(info);TpZxfjkcSylrzb mx_sylr = sylrService.queryMx(info);if(mx_znjy == null && mx_jxjy ==null && mx_zfdk == null && mx_zfzj == null && mx_sylr == null) {continue;}String execlName = "【"+nsr.getXm()+"】"+"_【"+nsr.getZzhm()+"】的专项附加扣除信息";//初始化byte[] outPut= null;InputStream inputStream = null;//execloutPut = excelExportServiceForZxfjkc.exportExcelForBZYS(mx_znjy,mx_jxjy,mx_zfdk,mx_zfzj,mx_sylr,"个人所得税专项附加扣除",qymc,(String) info.get("qynbm"));int length = outPut.length;inputStream = new ByteArrayInputStream(outPut, 0, length);excelExportServiceForZxfjkc.execute(path + execlName + ".xlsx", inputStream);//将文件放进listsrcFile.add(new File(path + execlName + ".xlsx"));}LOGGER.info("所有Execl文件 都已写入临时目录");// 将服务器上存放Excel的文件夹打成zip包File zipFile = new File(path + "专项附加扣除信息(导出)" + ".zip");// 将多个excel打包成zip文件excelExportServiceForZxfjkc.zipFiles(srcFile, zipFile);//下载//实现将压缩包写入流中,下载到本地,并删除临时文件中的压缩包及文件excelExportServiceForZxfjkc.downFile(response, path, "专项附加扣除信息(导出)" + ".zip");System.out.println("压缩包成功通过浏览器中下载下来------");} catch (Exception e) {//输出错误信息LOGGER.error(Toolkits.getExceptionInfo(e));}return null;}

尾语

poi功能虽然强大,但实际开发过程中,需要写大量重复代码,太麻烦了,easyexcel应允而生。easyexcel 是阿里巴巴开源的一款 excel 解析工具,底层逻辑也是基于 apache poi 进行二次开发的。不同的是,再读写数据的时候,采用 sax 模式一行一行解析,在并发量很大的情况下,依然能稳定运行。缺点就是读写性能稍慢。

大家感兴趣的话,多多留言交流,点个关注在走,小牛会及时更新后续之作easyexcel的入门篇。

Java 读写 Execl实战入门--打包多份Excel生成Zip进行下载相关推荐

  1. java项目开发实战入门电子书,java项目开发实战入门全彩版

    <JaWeb项目开发实战入门>以企业门户网.51商城.BBS--程序源论坛.YouKnow问卷.OA办公自动化系统.铭成在线考试系统.K12(中小学)综合测评系统和Show--企业个性化展 ...

  2. java架构师入门教程,java技术架构师入门到精通高薪就业教程百度云下载

    java技术架构师入门到精通高薪就业视频教程百度云 课程目录: JAVA架构课开班典礼 JVM性能调优专题 JVM整体结构深度解析 JVM内存分配机制详解(此视频作废) JVM字节码文件结构深度剖析 ...

  3. android APP读写execl文件,文件管理器查看excel文件

    我想在我的APP里面读写excel文档,然后在手机的文件管理里面查看这个excel文档.我找了一个例子,在app里面写了一个excel文档. 问题一.我在想文档存放在哪里呢?看下面的代码吧. prin ...

  4. php 生成zip并下载,PHP 实现文件打包成zip格式并下载

    PHP 文件打包并下载 有个这样的需求,将多个文件打包成zip格式并下载到本地 可根据 ZipArchive这个类来实现此功能 我自己也研究了一下,然后把搞出来了 ,经测试绝对好用 话不多说直接上代码 ...

  5. 视频教程-Spring Boot实战入门视频课程-Java

    Spring Boot实战入门视频课程 国内上市大型医疗软件公司产品研发部总经理,技术培训总监.6年以上大型项目一线开发.架构.管理经验,曾主导医疗大数据+移动BI产品设计与研发.技术狂热爱好者,擅长 ...

  6. Java学习路线,java学习教程(入门到精通)

    你好,欢迎来到编程领域:阅读"Java入门",打包好了Java学习包,以及良好的阅读体验. 关于 Java 语言 由于 JVM 的支持,使得 Java 成为一种跨平台的编程语言,一 ...

  7. 自己的模块给其他人调用是怎么打包的_webpack实战——模块打包

    写在前面 这是webpack实战系列的第二篇:模块和模块打包.上一篇:webpack实战--打包第一个应用 记录了webpack的一些基础内容与一个简单的小例子,开启了webpack的实战之路,这一篇 ...

  8. java单线程共享,「Java并发编程实战」之对象的共享

    前言 本系列博客是对<Java并发编程实战>的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥.可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(term ...

  9. python全栈工程师 pdf_python全栈工程师项目开发实例实战入门教程百度云

    python全栈工程师项目开发实例实战入门教程百度云 课程目录: 开学典礼 pycharm的基本使用 Python基本语法 数值类型数据及运算 字符串的基本操作 字符串的常用方法 列表的基本使用 列表 ...

最新文章

  1. NVIDIA深度学习Tensor Core性能解析(上)
  2. SAMBA服务和FTP服务讲解(week3_day1)--技术流ken
  3. 【powerdesigner】将pdm或者cdm保存为普通图片格式
  4. xd可以用ui动效效果吗_通过动画使UI设计栩栩如生:Adobe XD和After Effects
  5. Chapter 5 Exercises Problems
  6. Activiti手动执行的应用(UserTask)
  7. win10远程计算机证书错误,win10系统下出现Wi-Fi证书错误的四种解决方案
  8. iOS多线程编程--NSOperation(转)
  9. 截取安卓直播APP中的视频流 -央视频或者斗鱼直播下载+
  10. caffe 连接 matlab2016b
  11. 蓝星微商城源码+搭建教程源码
  12. OpenFeign实现微服务间的文件下载
  13. Jeff Dean执笔:一文看尽2018谷歌AI重大成果
  14. kill word out e ef en em
  15. 反函数的导数 基本初等函数的求导公式
  16. 无线WiFi怎样实现实名认证?
  17. Day25 - Event Capture, Propagation, Bubbling and Once
  18. Echarts 漏斗图
  19. 运维工程师应该具备的技能(转载)
  20. 市场模式缭乱,合适的模式脱颖而出?众筹卖货模式在线分享分析

热门文章

  1. BNO55移植到STM32平台及其他单片机平台
  2. 关于 iOS 开发者账号过期的总结
  3. 什么是RDB和ROF? 一文了解Redis持久化
  4. [转载] Web services 世界的业务过程和工作流
  5. Unity编辑器扩展批量生成游戏子物体
  6. SpringBoot智能养老公寓系统
  7. halcon中的弧度角度互换
  8. 札记:如何理解计算机里的卷积——把周围关联信息加权求和,更新本节点的值
  9. python学习总结记录
  10. THE ANATOMY OF AN INVITE REQUEST 解析一个invite request