使用 POI 设置 Excel 格式
POI 的使用
阿帕奇的一个框架,不知道的自行百度一下吧。
先说下都有哪些创建方式,以及各个的区别吧。POI的一些使用方法:
- 创建流程(上级为下级的载体):
- 创建Workbook(工作薄);
- 创建Sheet(表单,可以创建多个);
- 创建Row(行);
- 创建Cell(单元格)
接下来分别说下工作簿的常用三种形式的区别,他们分别是 1.HSSFWorkbook 2.XSSFWorkbook 3.SXSSFWorkbook:
1 2 3 4 5 6 7 8 9
| XSSFWorkbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet();
Row rowHeader = sheet.createRow(0);
Cell cell = rowHeader.createCell(0, CellType.STRING);
cell.setCellValue("报表");
|
这些是设置行列的用法,循环组合起来就可以写入报表具体数据,最后面会放一个demo。
vue使用axios请求后端去返回下载流这种,必须使用==responseType: ‘blob’==:
1 2 3 4 5
| export: params => { return Axios.post(`${api}report/exportreport`, params, { responseType: 'blob' }) },
|
vue写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| buSupportSevConfig.export(params).then(res => { const url = window.URL.createObjectURL(new Blob([res.data], { type: 'application/vnd.ms-excel' })); const link = document.createElement('a'); link.href = url; link.setAttribute('download', '综合查询结果导出表.xlsx'); link.style.display = 'none' document.body.appendChild(link); link.click();
document.body.removeChild(link); window.URL.revokeObjectURL(url); })
|
后端写法:
1 2 3 4 5 6
| response.setContentType("application/vnd.ms-excel"); String resultFileName = URLEncoder.encode(fileName, "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + resultFileName + ";" + "filename*=utf-8''" + resultFileName); workbook.write(response.getOutputStream()); workbook.close(); response.flushBuffer();
|
设置 Excel 格式
合并单元格
1 2 3
| CellRangeAddress region = new CellRangeAddress(0, 0, 0, headerList.size()); sheet.addMergedRegion(region);
|
带斜线的单元格
这里给一种简单的写法,复杂表格画斜线最好使用这种Java中使用POI在Excel单元格中画斜线—XLS格式 - 简书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| XSSFSheet sheet = wb.createSheet("Sheet1"); CreationHelper helper = wb.getCreationHelper(); XSSFDrawing drawing = sheet.createDrawingPatriarch(); Row rowHeadertou = sheet.createRow(1); ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(0); anchor.setRow1(1);
anchor.setCol2(1); anchor.setRow2(2); XSSFSimpleShape shape = drawing.createSimpleShape((XSSFClientAnchor) anchor);
shape.setShapeType(ShapeTypes.LINE);
shape.setLineWidth(0.5);
shape.setLineStyle(0);
shape.setLineStyleColor(0, 0, 0);
|
效果就是这种:

需要调整宽和高:
1 2 3 4 5
|
sheet.setColumnWidth(i, 50 * 100);
rowHeadertou.setHeight((short)(18*45));
|
设置边框、字体、加粗、居中等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| XSSFWorkbook workbook = new XSSFWorkbook(); CellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
Font titleFont = workbook.createFont();
titleFont.setFontName("宋体");
titleFont.setFontHeight((short) 10);
titleFont.setColor((short) 111);
titleFont.setBold(true);
titleFont.setFontHeightInPoints((short) 12); style.setFont(titleFont);
style.setBorderBottom(BorderStyle.THICK); style.setBorderRight(BorderStyle.THICK); style.setBorderTop(BorderStyle.THICK);
|
边框这种东西如果用代码设置会非常麻烦,所以如果有复杂的单元格设置或者表头的,最好是使用模板,就是先创建一个设置好的模板,然后用代码去复制一个模板文件,读取模板,往里面写入数据。
基于模板导出的工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
| package com.cars.tsbdas.common;
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RestController;
@RestController public class ExcelUtils {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
public static final String SUCCESS = "success";
public static final String FAIL = "fail";
private static String templatePath;
private static String exportPath;
public static void exportExcel(List<List<List<String>>> result, HttpServletResponse response, String fileName, int sheetNum, int createRowNum, int createCellNum) {
File newFile = createNewFile(fileName); InputStream is = null; XSSFWorkbook workbook = null; XSSFSheet sheet = null; try { is = new FileInputStream(newFile); workbook = new XSSFWorkbook(is); if (result.size() > 0) { for (int i = 0; i < result.size(); i++) { sheet = workbook.getSheetAt(i); ExcelUtils.writeIOData(result.get(i), newFile, workbook, sheet, createRowNum, createCellNum); } } InputStream fis = new BufferedInputStream(new FileInputStream(newFile)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); response.reset(); response.setContentType("text/html;charset=UTF-8"); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/x-msdownload"); String newName = URLEncoder.encode(fileName + System.currentTimeMillis() + ".xlsx", "UTF-8"); response.addHeader("Content-Disposition", "attachment;filename=\"" + newName + "\""); response.addHeader("Content-Length", "" + newFile.length()); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (Exception e1) { e1.printStackTrace(); logger.error("readExcel" + ExcelUtils.FAIL, e1); } finally { try { if (null != is) { is.close(); } } catch (Exception e) { e.printStackTrace(); } } }
private static void writeIOData(List<List<String>> result, File newFile, XSSFWorkbook workbook, XSSFSheet sheet, int createRowNum, int createCellNum) throws IOException { FileOutputStream fos = new FileOutputStream(newFile); XSSFRow row = sheet.getRow(createRowNum); if (row == null) { row = sheet.createRow(createRowNum); } XSSFCell cell = row.getCell(createCellNum); if (cell == null) { cell = row.createCell(createCellNum); } int cellNum = result.get(0).size(); for (int m = 1; m < result.size(); m++) { row = sheet.createRow((int) m + 1); List<String> tempList = result.get(m); for (int i = 0; i < cellNum; i++) { String str = tempList.get(i); cell = row.createCell(i); cell.setCellValue(str); } } workbook.write(fos); fos.flush(); fos.close(); }
public static void fileChannelCopy(File s, File t) { try { InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(s), 1024); out = new BufferedOutputStream(new FileOutputStream(t), 1024); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } } finally { if (null != in) { in.close(); } if (null != out) { out.close(); } } } catch (Exception e) { logger.error("templateFile copy exportFile" + ExcelUtils.FAIL, e); e.printStackTrace(); } }
private static String getSispPath() { String classPaths = ExcelUtils.class.getResource("/").getPath(); String[] aa = classPaths.split("/"); String sispPath = ""; for (int i = 1; i < aa.length - 2; i++) { sispPath += aa[i] + "/"; } return sispPath; }
public static File createNewFile(String fileName) { String path = (getSispPath() + templatePath +"/" + fileName +".xlsx"); File file = new File(path); String realPath = (getSispPath() + exportPath +"/"); File dir = new File(realPath); if (!dir.exists()) { dir.mkdirs(); } else { ExcelUtils.deleteFile(dir.listFiles()); logger.info("delete exportFile" + ExcelUtils.SUCCESS); } File newFile = new File(realPath, fileName); try { newFile.createNewFile(); fileChannelCopy(file, newFile); } catch (Exception e) { e.printStackTrace(); } return newFile; }
private static void deleteFile(File... files) { for (File file : files) { if (file.exists()) { file.delete(); } } }
@Value("${template.path}") public void setTemplatePath(String templatePath) { ExcelUtils.templatePath = templatePath; }
@Value("${export.path}") public void setExportPath(String exportPath) { ExcelUtils.exportPath = exportPath; } }
|
基于类反射生成 Excel 文件的工具类
如果数据是动态组合,那就不能用这种class反射方式去生成列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
public static void exportExcel(String fileName, List<?> objects, Class<?> c, HttpServletResponse response) throws Exception { try { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); Row rowHeader = sheet.createRow(0); if (c == null) { throw new RuntimeException("Class对象不能为空!"); } Field[] declaredFields = c.getDeclaredFields(); List<String> headerList = new ArrayList<>(); if (declaredFields.length == 0) { return; }
for (int i = 0; i < declaredFields.length; i++) { Cell cell = rowHeader.createCell(i, CellType.STRING); String headerName = String.valueOf(declaredFields[i].getName()); cell.setCellValue(headerName); headerList.add(i, headerName); }
Object obj = c.newInstance(); if (!CollectionUtils.isEmpty(objects)) { for (int o = 0; o < objects.size(); o++) { Row rowData = sheet.createRow(o + 1); for (int i = 0; i < headerList.size(); i++) { Cell cell = rowData.createCell(i); Field nameField = c.getDeclaredField(headerList.get(i)); nameField.setAccessible(true); String value = String.valueOf(nameField.get(objects.get(o))); cell.setCellValue(value); } } }
response.setContentType("application/vnd.ms-excel"); String resultFileName = URLEncoder.encode(fileName, "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + resultFileName + ";" + "filename*=utf-8''" + resultFileName); workbook.write(response.getOutputStream()); workbook.close(); response.flushBuffer(); } catch (Exception e) { throw new RuntimeException(e); } }
|