java通过poi导出excel
PS:这几天项目中用到poi导出数据至excel,这里将poi导出excel再回忆下。
一、创建空的springboot项目,在pom文件中加入操作Excel所需要的jar
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency>
此处注意 org.apache.poi下有很多依赖包,我们选择我们此次操作excel(.xls、.XLSX)所需要的依赖,选择poi-ooxml即可。
此处附上官网说明(http://poi.apache.org/components/)
二、工具类
在POI中操作Excel大致分为两种,2003版本和2007版本及以上,前者最大支持65536行,后者最大支持1048576行,两种所使用的工具类是不一样的(例如03使用HSSFWorkbook,07使用XSSFWorkbook)。
2003版的最大不能超过65535行,2007版没测出来,内存溢出了
1、 2007版工具方法(无或者只有1行标题)
/** *@Description:03版后缀.xls,标题可有可无,如无标题则headers传null即可 *@Param: title excel名称,也可当sheet页名称使用 *@Param: headers 标题 *@Param: dataset 数据集 *@Param: out 输出流 *@Param: dataset 数据集,此处必须为Map *@Param: pattern 如果表格中有时间类型按照这种格式展示 *@Param: keys 数据集中Map的字段名称 *@return:void *@Author: 张江坤 *@date: 2021/2/24 21:54 */ public static void exportExcel2003(String title, String[] headers, List<Map<String,Object>> dataset, OutputStream out, String pattern,List<String> keys) { // 声明一个工作薄 HSSFWorkbook workbook = new HSSFWorkbook(); // 生成一个表格 HSSFSheet sheet = workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth(20); // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋体"); font.setColor(HSSFColor.WHITE.index); font.setFontHeightInPoints((short) 11); // 把字体应用到当前的样式 style.setFont(font); // 生成并设置另一个样式 HSSFCellStyle style2 = workbook.createCellStyle(); style2.setFillForegroundColor(HSSFColor.WHITE.index); style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); style2.setBorderLeft(HSSFCellStyle.BORDER_THIN); style2.setBorderRight(HSSFCellStyle.BORDER_THIN); style2.setBorderTop(HSSFCellStyle.BORDER_THIN); style2.setAlignment(HSSFCellStyle.ALIGN_CENTER); style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成另一个字体 HSSFFont font2 = workbook.createFont(); font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); // 把字体应用到当前的样式 style2.setFont(font2); HSSFRow row; //有无标题,适应于标题在数据集中 if(null != headers){ // 产生表格标题行 row = sheet.createRow(0); HSSFCell cellHeader; for (int i = 0;i < headers.length; i++) { cellHeader = row.createCell(i); cellHeader.setCellStyle(style); cellHeader.setCellValue(new HSSFRichTextString(headers[i])); } } if(!dataset.isEmpty()) { // 遍历集合数据,产生数据行 Iterator<Map<String,Object>> it = dataset.iterator(); //如果没有标题,则从第0行开始写数据 int index = null==headers ? -1 : 0; Map<String,Object> t; Field field; HSSFRichTextString richString; Pattern p = Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher; HSSFCell cell; Object value; String textValue; SimpleDateFormat sdf = new SimpleDateFormat(pattern); while (it.hasNext()) { index++; row = sheet.createRow(index); t = (Map<String,Object>) it.next(); for (int i = 0; i < keys.size(); i++) { cell = row.createCell(i); cell.setCellStyle(style2); try { value = t.get(keys.get(i)); // 判断值的类型后进行强制类型转换 textValue = null; if (value instanceof Integer) { cell.setCellValue((Integer) value); } else if (value instanceof Float) { textValue = String.valueOf((Float) value); cell.setCellValue(textValue); } else if (value instanceof Double) { textValue = String.valueOf((Double) value); cell.setCellValue(textValue); } else if (value instanceof Long) { cell.setCellValue((Long) value); } if (value instanceof Boolean) { textValue = "是"; if (!(Boolean) value) { textValue = "否"; } } else if (value instanceof Date) { textValue = sdf.format((Date) value); } else { // 其它数据类型都当作字符串简单处理 if (value != null) { textValue = value.toString(); } } if (textValue != null) { matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { richString = new HSSFRichTextString(textValue); cell.setCellValue(richString); } } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { // 清理资源 } } } } try { workbook.write(out); } catch (IOException e) { e.printStackTrace(); } }
2、2007版工具方法(无或者只有1行标题,较2003版,更替了工具类,逻辑一样,粘贴此处方便使用)
/** *@Description:07版后缀.xlsx,标题可有可无,如无标题则headers传null即可 *@Param: title excel名称,也可当sheet页名称使用 *@Param: headers 标题 *@Param: dataset 数据集 *@Param: out 输出流 *@Param: dataset 数据集,此处必须为Map *@Param: pattern 如果表格中有时间类型按照这种格式展示 *@Param: keys 数据集中Map的字段名称 *@return:void *@Author: 张江坤 *@date: 2021/2/24 21:54 */ public static void exportExcel2007(String title, String[] headers, List<Map<String,Object>> dataset, OutputStream out, String pattern,List<String> keys) { // 声明一个工作薄 XSSFWorkbook workbook = new XSSFWorkbook(); // 生成一个表格 XSSFSheet sheet = workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth(20); // 生成一个样式 XSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(new XSSFColor(Color.gray)); style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(XSSFCellStyle.BORDER_THIN); style.setBorderLeft(XSSFCellStyle.BORDER_THIN); style.setBorderRight(XSSFCellStyle.BORDER_THIN); style.setBorderTop(XSSFCellStyle.BORDER_THIN); style.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 生成一个字体 XSSFFont font = workbook.createFont(); font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋体"); font.setColor(new XSSFColor(Color.BLACK)); font.setFontHeightInPoints((short) 11); // 把字体应用到当前的样式 style.setFont(font); // 生成并设置另一个样式 XSSFCellStyle style2 = workbook.createCellStyle(); style2.setFillForegroundColor(new XSSFColor(Color.WHITE)); style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); style2.setBorderBottom(XSSFCellStyle.BORDER_THIN); style2.setBorderLeft(XSSFCellStyle.BORDER_THIN); style2.setBorderRight(XSSFCellStyle.BORDER_THIN); style2.setBorderTop(XSSFCellStyle.BORDER_THIN); style2.setAlignment(XSSFCellStyle.ALIGN_CENTER); style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER); // 生成另一个字体 XSSFFont font2 = workbook.createFont(); font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL); // 把字体应用到当前的样式 style2.setFont(font2); XSSFRow row; //有无标题,取决于标题是否在数据集中 if(null != headers){ // 产生表格标题行 row = sheet.createRow(0); XSSFCell cellHeader; for (int i = 0;i < headers.length; i++) { cellHeader = row.createCell(i); cellHeader.setCellStyle(style); cellHeader.setCellValue(new XSSFRichTextString(headers[i])); } } if(!dataset.isEmpty()) { // 遍历集合数据,产生数据行 Iterator<Map<String,Object>> it = dataset.iterator(); //如果没有标题,则从第0行开始写数据 int index = null==headers ? -1 : 0; Map<String,Object> t; Field field; XSSFRichTextString richString; Pattern p = Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher; XSSFCell cell; Object value; String textValue; SimpleDateFormat sdf = new SimpleDateFormat(pattern); while (it.hasNext()) { index++; row = sheet.createRow(index); t = (Map<String,Object>) it.next(); for (int i = 0; i < keys.size(); i++) { cell = row.createCell(i); cell.setCellStyle(style2); try { value = t.get(keys.get(i)); // 判断值的类型后进行强制类型转换 textValue = null; if (value instanceof Integer) { cell.setCellValue((Integer) value); } else if (value instanceof Float) { textValue = String.valueOf((Float) value); cell.setCellValue(textValue); } else if (value instanceof Double) { textValue = String.valueOf((Double) value); cell.setCellValue(textValue); } else if (value instanceof Long) { cell.setCellValue((Long) value); } if (value instanceof Boolean) { textValue = "是"; if (!(Boolean) value) { textValue = "否"; } } else if (value instanceof Date) { textValue = sdf.format((Date) value); } else { // 其它数据类型都当作字符串简单处理 if (value != null) { textValue = value.toString(); } } if (textValue != null) { matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { richString = new XSSFRichTextString(textValue); cell.setCellValue(richString); } } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { // 清理资源 } } } } try { workbook.write(out); } catch (IOException e) { e.printStackTrace(); } }
3、03版标题合并类型工具方法
/** *@Description:03版 .xls *@Param: title excel名称,也可当sheet页名称使用 *@Param: headers_1 未合并的第一部分标题 *@Param: headers_2 合并单元格的大标题 *@Param: headers_3 不合并的第二部分列名 *@Param: headers_4 合并单元格的小标题 *@Param: nums 合并列中每大列占几小列,例如 [3,3]第1,2大列各占3小列 *@Param: keys 数据集中Map的字段名称 *@Param: dataset 数据集,此处必须为Map *@Param: out 输出流 *@Param: pattern 如果表格中有时间类型按照这种格式展示 *@return:void *@Author: 张江坤 *@date: 2021/2/23 13:48 */ public static void exportExcel2003(String title, String[] headers_1,String[] headers_2,String[] headers_3, String[] headers_4, int[] nums, List<Map<String,Object>> dataset, List<String> keys, OutputStream out, String pattern) { // 声明一个工作薄 HSSFWorkbook workbook = new HSSFWorkbook(); // 生成一个表格 HSSFSheet sheet = workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth(20); // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋体"); font.setColor(HSSFColor.WHITE.index); font.setFontHeightInPoints((short) 11); // 把字体应用到当前的样式 style.setFont(font); // 生成并设置另一个样式 HSSFCellStyle style2 = workbook.createCellStyle(); style2.setFillForegroundColor(HSSFColor.WHITE.index); style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); style2.setBorderLeft(HSSFCellStyle.BORDER_THIN); style2.setBorderRight(HSSFCellStyle.BORDER_THIN); style2.setBorderTop(HSSFCellStyle.BORDER_THIN); style2.setAlignment(HSSFCellStyle.ALIGN_CENTER); style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成另一个字体(标题跟正文分开) HSSFFont font2 = workbook.createFont(); font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); // 把字体应用到当前的样式 style2.setFont(font2); HSSFRow row = sheet.createRow(0); //设置未合并的第一部分列的格式 for(int i=0; i<headers_1.length; i++){ //占2行1列(因为有合并行,合并列) CellRangeAddress cra=new CellRangeAddress(0, 1, i, i); sheet.addMergedRegion(cra); } //为未合并行的第一部分列写入标题 for(int i=0; i<headers_1.length; i++){ final Cell cell = row.createCell(i); cell.setCellStyle(style); cell.setCellValue(headers_1[i]); } int sum1 = 0; int sum2 = 0; //合并列的大标题 for(int i=0; i<headers_2.length; i++){//受理数,办结数 sum1 += nums[i]; //占1行,从header_2长度后的那列开始数,画够合并行的宽度 CellRangeAddress cra=new CellRangeAddress(0, 0, headers_1.length+sum2, headers_1.length+sum1-1); sheet.addMergedRegion(cra); sum2 += nums[i]; } int sum = 0; for(int i=0; i<headers_2.length; i++){ //给合并列中的大列写入标题,未合并列第一部分宽度 + 合并列各列中小列的宽度 final Cell cell = row.createCell(headers_1.length+sum); cell.setCellStyle(style); cell.setCellValue(headers_2[i]); sum += nums[i]; } //未合并列的第二部分列设置格式,占2行1列 for(int i=0; i<headers_3.length; i++){ CellRangeAddress cra=new CellRangeAddress(0, 1, headers_1.length+sum2+i, headers_2.length+sum2+i); sheet.addMergedRegion(cra); } //给未合并列的第二部分列写入标题 for(int i=0; i<headers_3.length; i++){ final Cell cell = row.createCell(headers_1.length+sum2+i); cell.setCellStyle(style); cell.setCellValue(headers_3[i]); } //重新创建一行,写入合并列中的小列 row = sheet.createRow(1); for(int i=0; i<headers_4.length; i++){ final Cell cell = row.createCell(headers_1.length+i); cell.setCellStyle(style); cell.setCellValue(headers_4[i]); } // 遍历集合数据,产生数据行 Iterator<Map<String,Object>> it = dataset.iterator(); int index = 1; Map<String,Object> t; HSSFRichTextString richString; Pattern p = Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher; HSSFCell cell; Object value; String textValue; SimpleDateFormat sdf = new SimpleDateFormat(pattern); while (it.hasNext()) { index++; row = sheet.createRow(index); t = (Map<String,Object>) it.next(); for (int i = 0; i < keys.size(); i++) { cell = row.createCell(i); cell.setCellStyle(style2); try { value = t.get(keys.get(i)); // 判断值的类型后进行强制类型转换 textValue = null; if (value instanceof Integer) { cell.setCellValue((Integer) value); } else if (value instanceof Float) { textValue = String.valueOf((Float) value); cell.setCellValue(textValue); } else if (value instanceof Double) { textValue = String.valueOf((Double) value); cell.setCellValue(textValue); } else if (value instanceof Long) { cell.setCellValue((Long) value); } if (value instanceof Boolean) { textValue = "是"; if (!(Boolean) value) { textValue = "否"; } } else if (value instanceof Date) { textValue = sdf.format((Date) value); } else { // 其它数据类型都当作字符串简单处理 if (value != null) { textValue = value.toString(); } } if (textValue != null) { matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { richString = new HSSFRichTextString(textValue); cell.setCellValue(richString); } } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { // 清理资源 } } } try { workbook.write(out); } catch (IOException e) { e.printStackTrace(); } }
4、07版标题合并类型工具方法
/** *@Description:07版 .xlsx *@Param: title excel名称,也可当sheet页名称使用 *@Param: headers_1 未合并的第一部分标题 *@Param: headers_2 合并单元格的大标题 *@Param: headers_3 不合并的第二部分列名 *@Param: headers_4 合并单元格的小标题 *@Param: nums 合并列中每大列占几小列,例如 [3,3]第1,2大列各占3小列 *@Param: keys 数据集中Map的字段名称 *@Param: dataset 数据集,此处必须为Map *@Param: out 输出流 *@Param: pattern 如果表格中有时间类型按照这种格式展示 *@return:void *@Author: 张江坤 *@date: 2021/2/23 13:48 */ public static void exportExcel2007(String title, String[] headers_1,String[] headers_2,String[] headers_3, String[] headers_4, int[] nums, List<Map<String,Object>> dataset, List<String> keys, OutputStream out, String pattern) { // 声明一个工作薄 XSSFWorkbook workbook = new XSSFWorkbook(); // 生成一个表格 XSSFSheet sheet = workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth(20); // 生成一个样式 XSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(new XSSFColor(Color.gray)); style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(XSSFCellStyle.BORDER_THIN); style.setBorderLeft(XSSFCellStyle.BORDER_THIN); style.setBorderRight(XSSFCellStyle.BORDER_THIN); style.setBorderTop(XSSFCellStyle.BORDER_THIN); style.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 生成一个字体 XSSFFont font = workbook.createFont(); font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋体"); font.setColor(new XSSFColor(Color.BLACK)); font.setFontHeightInPoints((short) 11); // 把字体应用到当前的样式 style.setFont(font); // 生成并设置另一个样式 XSSFCellStyle style2 = workbook.createCellStyle(); style2.setFillForegroundColor(new XSSFColor(Color.WHITE)); style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); style2.setBorderBottom(XSSFCellStyle.BORDER_THIN); style2.setBorderLeft(XSSFCellStyle.BORDER_THIN); style2.setBorderRight(XSSFCellStyle.BORDER_THIN); style2.setBorderTop(XSSFCellStyle.BORDER_THIN); style2.setAlignment(XSSFCellStyle.ALIGN_CENTER); style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER); // 生成另一个字体(标题跟正文分开) XSSFFont font2 = workbook.createFont(); font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL); // 把字体应用到当前的样式 style2.setFont(font2); XSSFRow row = sheet.createRow(0); //设置未合并的第一部分列的格式 for(int i=0; i<headers_1.length; i++){ //占2行1列(因为有合并行,合并列) CellRangeAddress cra=new CellRangeAddress(0, 1, i, i); sheet.addMergedRegion(cra); } //为未合并行的第一部分列写入标题 for(int i=0; i<headers_1.length; i++){ final Cell cell = row.createCell(i); cell.setCellStyle(style); cell.setCellValue(headers_1[i]); } int sum1 = 0; int sum2 = 0; //合并列的大标题 for(int i=0; i<headers_2.length; i++){//受理数,办结数 sum1 += nums[i]; //占1行,从header_2长度后的那列开始数,画够合并行的宽度 CellRangeAddress cra=new CellRangeAddress(0, 0, headers_1.length+sum2, headers_1.length+sum1-1); sheet.addMergedRegion(cra); sum2 += nums[i]; } int sum = 0; for(int i=0; i<headers_2.length; i++){ //给合并列中的大列写入标题,未合并列第一部分宽度 + 合并列各列中小列的宽度 final Cell cell = row.createCell(headers_1.length+sum); cell.setCellStyle(style); cell.setCellValue(headers_2[i]); sum += nums[i]; } //未合并列的第二部分列设置格式,占2行1列 for(int i=0; i<headers_3.length; i++){ CellRangeAddress cra=new CellRangeAddress(0, 1, headers_1.length+sum2+i, headers_2.length+sum2+i); sheet.addMergedRegion(cra); } //给未合并列的第二部分列写入标题 for(int i=0; i<headers_3.length; i++){ final Cell cell = row.createCell(headers_1.length+sum2+i); cell.setCellStyle(style); cell.setCellValue(headers_3[i]); } //重新创建一行,写入合并列中的小列 row = sheet.createRow(1); for(int i=0; i<headers_4.length; i++){ final Cell cell = row.createCell(headers_1.length+i); cell.setCellStyle(style); cell.setCellValue(headers_4[i]); } // 遍历集合数据,产生数据行 Iterator<Map<String,Object>> it = dataset.iterator(); int index = 1; Map<String,Object> t; XSSFRichTextString richString; Pattern p = Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher; XSSFCell cell; Object value; String textValue; SimpleDateFormat sdf = new SimpleDateFormat(pattern); while (it.hasNext()) { index++; row = sheet.createRow(index); t = (Map<String,Object>) it.next(); for (int i = 0; i < keys.size(); i++) { cell = row.createCell(i); cell.setCellStyle(style2); try { value = t.get(keys.get(i)); // 判断值的类型后进行强制类型转换 textValue = null; if (value instanceof Integer) { cell.setCellValue((Integer) value); } else if (value instanceof Float) { textValue = String.valueOf((Float) value); cell.setCellValue(textValue); } else if (value instanceof Double) { textValue = String.valueOf((Double) value); cell.setCellValue(textValue); } else if (value instanceof Long) { cell.setCellValue((Long) value); } if (value instanceof Boolean) { textValue = "是"; if (!(Boolean) value) { textValue = "否"; } } else if (value instanceof Date) { textValue = sdf.format((Date) value); } else { // 其它数据类型都当作字符串简单处理 if (value != null) { textValue = value.toString(); } } if (textValue != null) { matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { richString = new XSSFRichTextString(textValue); cell.setCellValue(richString); } } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { // 清理资源 } } } try { workbook.write(out); } catch (IOException e) { e.printStackTrace(); } }
调用总入口
@RequestMapping("/exportExcel/{fileName}") public void exportExcle(@PathVariable("fileName") String fileName, HttpServletResponse response){ response.setContentType("application/vnd.ms-excel;charset=UTF-8"); try { response.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8") + ".xlsx");//03版后缀为.xls 07版后缀为.xlsx } catch (UnsupportedEncodingException e) { e.printStackTrace(); } List<Map<String,Object>> list = new ArrayList<>(); for(int i=0;i<10;i++){ Map<String,Object> map = new HashMap<>(); map.put("one","第"+(i+1)+"行的值"); map.put("two","第"+(i+1)+"行的值"); map.put("three","第"+(i+1)+"行的值"); map.put("four","第"+(i+1)+"行的值"); map.put("five","第"+(i+1)+"行的值"); map.put("six","第"+(i+1)+"行的值"); map.put("seven","第"+(i+1)+"行的值"); map.put("eight","第"+(i+1)+"行的值"); map.put("nine","第"+(i+1)+"行的值"); map.put("ten","第"+(i+1)+"行的值"); list.add(map); } List<String> keys = Arrays.asList("one","two","three","four","five","six","seven","eight","nine","ten"); String[] headers = {"第1列","第2列","第3列","第4列","第5列","第6列","第7列","第8列","第9列","第10列"}; String[] headers_1 = {"部门","姓名"}; String[] headers_2 = {"受理量","办结量"}; String[] headers_3 = {"退件","补件"}; String[] headers_4 = {"承诺件","即办件","总量","承诺件","即办件","总量"}; int[] num = {3,3};//合并单元格各占列数 try { //以下调用一次执行一个 //03版单一标题 //ExportExcelUtil.exportExcel2003(fileName, headers, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys); //07版无标题 //ExportExcelUtil.exportExcel2007(fileName, null, list, response.getOutputStream(), "yyyy-MM-dd hh:mm:ss",keys); //03版单元格合并 //ExportExcelUtil.exportExcel2003(fileName,headers_1,headers_2,headers_3,headers_4,num,list,keys,response.getOutputStream(),"yyyy-MM-dd hh:mm:ss"); //07版单元格合并 ExportExcelUtil.exportExcel2007(fileName,headers_1,headers_2,headers_3,headers_4,num,list,keys,response.getOutputStream(),"yyyy-MM-dd hh:mm:ss"); } catch (IOException e) { e.printStackTrace(); } }
无标题
有标题
单元格合并
~~ 学如逆水行舟 不进则退