- 😜作 者:是江迪呀
- ✒️本文关键词:
Java
、Excel
、导出
、工具类
、后端
- ☀️每日 一言:有些事情不是对的才去坚持,而是坚持了它才是对的!
我们在日常开发中,一定遇到过要将数据导出为Excel
的需求,那么怎么做呢?在做之前,我们需要思考下Excel
的组成。Excel
是由四个元素组成的分别是:WorkBook(工作簿)
、Sheet(工作表)
、Row(行)
、Cell(单元格)
,其中包含关系是从左至右,,一个WorkBook
可以包含多个Sheet
,一个Sheet
又是由多个Row
组成,一个Row
是由多个Cell
组成。知道这些后那么我们就使用java
来将数据以Excel
的方式导出。让我们一起来学习吧✏️!
使用Java
实现将数据以Excel
的方式导出,需要依赖第三方的库。我们需要再pom.xml
中引入下面的依赖:
org.apache.poi poi 4.1.2 org.apache.poi poi-ooxml 4.1.2
2.1 创建Excel
的元素
(1)创建WokrBook
Workbook workbook = new XSSFWorkbook();
(2)创建Sheet
Sheet sheet = workbook.createSheet();
设置sheet
的名称
Sheet sheet = workbook.createSheet("sheet名称");
(3)创建行Row
Row row = sheet.createRow(0);
(4)创建单元格Cell
Cell cell = row.createCell(0, CellType.STRING);
可以指定单元格的类型,支持的类型有下面7种:
_NONE(-1), NUMERIC(0), STRING(1), //公式 FORMULA(2), BLANK(3), //布尔 BOOLEAN(4), ERROR(5);
(5) 填充数据
cell.setCellValue("苹果");
2.3 样式和字体
如果我们需要导出的Excel
美观一些,如设置字体的样式加粗、颜色、大小等等,就需要创建样式和字体。
创建样式:
CellStyle cellStyle = workbook.createCellStyle();
(1)左右垂直居中
//左右居中excelTitleStyle.setAlignment(HorizontalAlignment.CENTER);// 设置垂直居中excelTitleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
(2)字体加粗、颜色
创建加粗样式并设置到CellStyle
中:
Font font = workbook.createFont();//字体颜色为红色font.setColor(IndexedColors.RED.getIndex());//字体加粗font.setBold(true);cellStyle.setFont(font);
指定Cell
单元格使用该样式:
cell.setCellStyle(style);
(3)调整列宽和高
Sheet sheet = workbook.createSheet();//自动调整列的宽度来适应内容sheet.autoSizeColumn(int column); // 设置列的宽度sheet.setColumnWidth(2, 20 * 256);
autoSizeColumn()
传递的参数就是要设置的列索引。setColumnWidth()
第一个参数是要设置的列索引,第二参数是具体的宽度值,宽度 = 字符个数 * 256(例如20个字符的宽度就是20 * 256)
(4)倾斜、下划线
Font font = workbook.createFont();font.setItalic(boolean italic); 设置倾斜font.setUnderline(byte underline); 设置下划线
2.4 进阶用法
(1)合并单元格
Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet(fileName);sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 5));
CellRangeAddress()
方法四个参数分别是fristRow
:起始行、lastRow
:结束行、fristCol
:起始列、lastCol
:结束列。
如果你想合并从第一行到第二行从一列到第十列的单元格(一共合并20格),那么就是CellRangeAddress(0,1,0,10)
。
(2)字段必填
//创建数据验证DataValidationHelper dvHelper = sheet.getDataValidationHelper();//创建要添加校验的单元格对象CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 10);//创建必填校验规则DataValidationConstraint constraint = validationHelper.createCustomConstraint("NOT(ISBLANK(A1))");//设置校验DataValidation validation = dvHelper.createValidation(constraint, addressList);//校验不通过 提示validation.setShowErrorBox(true);sheet.addValidationData(validation);
CellRangeAddressList()
方法传递四个参数,分别是:fristRow
:起始行、lastRow
:结束行、fristCol
:起始列、lastCol
:结束列。CellRangeAddressList(0, 0, 0, 10)
表示的就是给第一行从第一列开始到第十列一共十个单元格添加数据校验。
(3)添加公式
- SUM:求和函数
//创建SUM公式FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();Cell sumCell = row.createCell(0);sumCell.setCellFormula("SUM(A1:A10)");//计算SUM公式结果Cell sumResultCell = row.createCell(1);sumResultCell.setCellValue(evaluator.evaluate(sumCell).getNumberValue());
- AVERAGE:平均数函数
//创建AVERAGE公式FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();Cell averageCell = row.createCell(0);averageCell.setCellFormula("AVERAGE(A1:A10)");//计算AVERAGE公式结果Cell averageResultCell = row.createCell(1);averageResultCell.setCellValue(evaluator.evaluate(averageCell).getNumberValue());
- COUNT:计数函数
//创建COUNT公式FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();Cell countCell = row.createCell(0);countCell.setCellFormula("COUNT(A1:A10)");//计算COUNT公式结果Cell countResultCell = row.createCell(1);countResultCell.setCellValue(evaluator.evaluate(countCell).getNumberValue());
- IF:条件函数
//创建IF公式FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();Cell ifCell = row.createCell(0);ifCell.setCellFormula("IF(A1>B1,\"Yes\",\"No\")");//计算IF公式结果Cell ifResultCell = row.createCell(1);ifResultCell.setCellValue(evaluator.evaluate(ifCell).getStringValue());
- CONCATENATE:连接函数
//创建CONCATENATE公式FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();Cell concatenateCell = row.createCell(0);concatenateCell.setCellFormula("CONCATENATE(A1,\" \",B1)");//计算CONCATENATE公式结果Cell concatenateResultCell = row.createCell(1);concatenateResultCell.setCellValue(evaluator.evaluate(concatenateCell).getStringValue());
(4)下拉选择
//下拉值private List grade = Arrays.asList("高", "中", "低");(此处省略n行代码)Sheet sheet = workbook.createSheet("sheet");DataValidation dataValidation = this.addPullDownConstraint(i, sheet, grade );sheet.addValidationData(dataValidation);
(5)设置单元格的数据类型
- 数字格式
// 设置单元格样式 - 数字格式CellStyle numberCellStyle = workbook.createCellStyle();numberCellStyle.setDataFormat(workbook.createDataFormat().getFormat("#,##0.00"));//指定单元格Row row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellStyle(numberCellStyle);
- 日期格式
// 设置单元格样式 - 日期格式CellStyle dateCellStyle = workbook.createCellStyle();dateCellStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-MM-dd"));//指定单元格Row row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellStyle(dateCellStyle);
下面的示例使用SpringBoot
项目来演示:
pom.xml
依赖:
org.springframework.boot spring-boot-starter-web 2.7.5 org.springframework.boot spring-boot-starter 2.7.5 org.apache.poi poi 4.1.2 org.apache.poi poi-ooxml 4.1.2 org.projectlombok lombok 1.16.16 com.alibaba fastjson 2.0.21 org.apache.commons commons-lang3 3.12.0
Controller
层代码:
package shijiangdiya.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import shijiangdiya.utils.ExportUtils;import javax.servlet.http.HttpServletResponse;@RestController@RequestMapping("/sync")public class ExportController {}
(1)代码
@Autowired private HttpServletResponse response; @PostMapping("/export") public void export() { //模拟json数据 String data = "[{\n" + " \"studentId\": \"20210101\",\n" + " \"name\": \"Alice\",\n" + " \"age\": 20,\n" + " \"credit\": 80\n" + " },\n" + " {\n" + " \"studentId\": \"20210102\",\n" + " \"name\": \"Bob\",\n" + " \"age\": 21,\n" + " \"credit\": 85\n" + " },\n" + " {\n" + " \"studentId\": \"20210103\",\n" + " \"name\": \"Charlie\",\n" + " \"age\": 22,\n" + " \"credit\": 90\n" + " },\n" + " {\n" + " \"studentId\": \"20210104\",\n" + " \"name\": \"David\",\n" + " \"age\": 20,\n" + " \"credit\": 75\n" + " },\n" + " {\n" + " \"studentId\": \"20210105\",\n" + " \"name\": \"Emily\",\n" + " \"age\": 21,\n" + " \"credit\": 82\n" + " },\n" + " {\n" + " \"studentId\": \"20210106\",\n" + " \"name\": \"Frank\",\n" + " \"age\": 22,\n" + " \"credit\": 88\n" + " },\n" + " {\n" + " \"studentId\": \"20210107\",\n" + " \"name\": \"Grace\",\n" + " \"age\": 20,\n" + " \"credit\": 81\n" + " },\n" + " {\n" + " \"studentId\": \"20210108\",\n" + " \"name\": \"Henry\",\n" + " \"age\": 21,\n" + " \"credit\": 89\n" + " },\n" + " {\n" + " \"studentId\": \"20210109\",\n" + " \"name\": \"Isaac\",\n" + " \"age\": 22,\n" + " \"credit\": 92\n" + " },\n" + " {\n" + " \"studentId\": \"20210110\",\n" + " \"name\": \"John\",\n" + " \"age\": 20,\n" + " \"credit\": 78\n" + " },\n" + " {\n" + " \"studentId\": \"20210111\",\n" + " \"name\": \"Kelly\",\n" + " \"age\": 21,\n" + " \"credit\": 84\n" + " },\n" + " {\n" + " \"studentId\": \"20210112\",\n" + " \"name\": \"Linda\",\n" + " \"age\": 22,\n" + " \"credit\": 87\n" + " },\n" + " {\n" + " \"studentId\": \"20210113\",\n" + " \"name\": \"Mike\",\n" + " \"age\": 20,\n" + " \"credit\": 77\n" + " },\n" + " {\n" + " \"studentId\": \"20210114\",\n" + " \"name\": \"Nancy\",\n" + " \"age\": 21,\n" + " \"credit\": 83\n" + " },\n" + " {\n" + " \"studentId\": \"20210115\",\n" + " \"name\": \"Oscar\",\n" + " \"age\": 22,\n" + " \"credit\": 91\n" + " },\n" + " {\n" + " \"studentId\": \"20210116\",\n" + " \"name\": \"Paul\",\n" + " \"age\": 20,\n" + " \"credit\": 76\n" + " },\n" + " {\n" + " \"studentId\": \"20210117\",\n" + " \"name\": \"Queen\",\n" + " \"age\": 21,\n" + " \"credit\": 86\n" + " },\n" + " {\n" + " \"studentId\": \"20210118\",\n" + " \"name\": \"Rachel\",\n" + " \"age\": 22,\n" + " \"credit\": 94\n" + " },\n" + " {\n" + " \"studentId\": \"20210119\",\n" + " \"name\": \"Sarah\",\n" + " \"age\": 20,\n" + " \"credit\": 79\n" + " },\n" + " {\n" + " \"studentId\": \"20210120\",\n" + " \"name\": \"Tom\",\n" + " \"age\": 21,\n" + " \"credit\": 80\n" + " }\n" + "]\n"; ExportUtils.exportExcel("学生信息", data, Student.class, response); }
(2)工具类
public static void exportExcel(String fileName, String data, 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 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); } // 填充数据 List> objects = JSONObject.parseArray(data, c); 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); } }
(2)结果
(1)代码
@PostMapping("/import") public void importExcel(@RequestParam("excel") MultipartFile excel){ Workbook workbook = null; try { workbook = WorkbookFactory.create(excel.getInputStream()); Sheet sheet = workbook.getSheetAt(0); List students = new ArrayList<>(); int i = 0; for (Row row : sheet) { Row row1 = sheet.getRow(i + 1); if(row1 != null){ Student data = new Student(); data.setStudentId(Integer.parseInt(row1.getCell(0).getStringCellValue())); data.setName(row1.getCell(1).getStringCellValue()); data.setAge(Integer.parseInt(row1.getCell(2).getStringCellValue())); data.setCredit(Integer.parseInt(row1.getCell(3).getStringCellValue())); students.add(data); } } System.out.println(students); workbook.close(); } catch (IOException e) { throw new RuntimeException(e); }
(2)工具类
public static List importExcel(Workbook workbook,Class> c){ List dataList = new ArrayList<>(); try { Sheet sheet = workbook.getSheetAt(0); int i = 0; T o = null; for (Row row : sheet) { Row row1 = sheet.getRow(i + 1); if(row1 != null){ o = (T) c.newInstance(); Field[] declaredFields = c.getDeclaredFields(); for (int i1 = 0; i1 < declaredFields.length; i1++) { String name = declaredFields[i1].getName(); Field declaredField1 = o.getClass().getDeclaredField(name); declaredField1.setAccessible(true); Cell cell = row1.getCell(i1); String type = declaredFields[i1].getType().getName(); String value = String.valueOf(cell); if(StringUtils.equals(type,"int") || StringUtils.equals(type,"Integer")){declaredField1.set(o,Integer.parseInt(value)); } else if(StringUtils.equals(type,"java.lang.String") || StringUtils.equals(type,"char") || StringUtils.equals(type,"Character") || StringUtils.equals(type,"byte") || StringUtils.equals(type,"Byte")){declaredField1.set(o,value); } else if(StringUtils.equals(type,"boolean") || StringUtils.equals(type,"Boolean")){declaredField1.set(o,Boolean.valueOf(value)); } else if(StringUtils.equals(type,"double") || StringUtils.equals(type,"Double")){declaredField1.set(o,Double.valueOf(value)); } else if (StringUtils.equals(type,"long") || StringUtils.equals(type,"Long")) {declaredField1.set(o,Long.valueOf(value)); } else if(StringUtils.equals(type,"short") || StringUtils.equals(type,"Short")){declaredField1.set(o,Short.valueOf(value)); } else if(StringUtils.equals(type,"float") || StringUtils.equals(type,"Float")){declaredField1.set(o,Float.valueOf(value)); } } } dataList.add(o); } workbook.close(); return dataList; }catch (Exception e){ e.printStackTrace(); } return dataList; }
注意:导入工具类仅限Java的八大基础数据类型
和String
类型。如果还有其他类型需要自己扩展。
(3)结果
学生信息集合:
来源地址:https://blog.csdn.net/qq_42785250/article/details/129654178