poi的使用
阿帕奇的一个框架,不知道的自行百度一下吧
先说下都有哪些创建方式,以及各个的区别吧
POI的一些使用方法:
创建流程:(上级为下级的载体)
1、创建Workbook(工作薄);
2、创建Sheet(表单,可以创建多个);
3、创建Row(行);
4、创建Cell(单元格)
接下来分别说下工作簿的常用三种形式的区别,他们分别是 1.HSSFWorkbook 2.XSSFWorkbook 3.SXSSFWorkbook
第一种:HSSFWorkbook
针对是 EXCEL2003 版本,扩展名为 .xls;所以此种的局限就是导出的行数至多为 65535 行,
此种因为行数不足七万行所以一般不会发生内存不足的情况(OOM);
第二种:XSSFWorkbook
这种形式的出现是由于第一种HSSFWorkbook的局限性而产生的,因为其所导出的行数比较少,所以XSSFWookbook应运而生,其对应的是EXCEL2007+(1048576行,16384列)扩展名.xlsx,最多可以导出104万行,不过这样就伴随着一个问题—OOM 内存溢出,原因是你所创建的book、sheet、row、cell等此时是存在内存的并没有持久化,那么随着数据量增大,内存的需求量也就增大,那么很大可能就是要OOM了,那么怎么解决呢?
第三种:SXSSFWorkbook poi.jar 3.8+
第二种遇到的问题该如何解决呢?因为数据量过大导致内存吃不消那么可以让内存到量持久化吗? 答案是肯定的,此种的情况就是设置最大内存条数,比如,设置最大内存量为5000 rows --new SXSSFWookbook(5000),此时当行数达到5000时,把内存持久化写到文件中,以此逐步写入 避免OOM,那么这样就完美解决了大数据下导出的问题
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
| 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);
|
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);
|
效果就是这种
![[danyuange.png]]
需要调整调整宽和高
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
| 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; } }
|
这是使用class类反射生成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); } }
|