最近在做SpringBoot项目,项目中需要上传Excel文件,对Excel文件中的内容进行解析,然后将需要的数据存入数据库,同时还要根据用户的需求,将需要的内容生成Excel文件,并下载下来。本篇主要是介绍Excel文件的生成以及下载,使用的开发工具是IDEA 。关于Excel文件的生成请移步SpringBoot项目中关于Excel的解析(一)
内容概要:
- 项目maven依赖
- Controller层代码
- 工具类HandleFile代码
- 测试结果
- 下载的Excel文件
一、项目maven依赖
需要注意的是:这里选择的poi-ooxml和poi的依赖版本最好一致,否则可能会有两个依赖会出现不匹配的问题。本人曾遇到过poi-ooxml的版本是3.9,poi的版本是3.13,最终在测试阶段报错:
java.lang.IllegalAccessError: tried to access method org.apache.poi.util.POILogger.log(ILjava/lang/Object;)V from class org.apache.poi.openxml4j.opc.PackageRelationshipCollection
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
二、Controller层
@RestController
@RequestMapping("/handleFile/")
@Slf4j
public class HandleFileController{
/**
* excel生成下载
* @param response
* @return
* @throws Exception
*/
@GetMapping(value = "/createExcel")
public String createExcel(HttpServletResponse response) throws Exception{
Map<String,Object> excelMap = new HashMap<>();
//1.设置Excel表头
List<String> headerList = new ArrayList<>();
headerList.add("用户id");
headerList.add("用户名");
headerList.add("性别");
headerList.add("身份证号");
headerList.add("注册时间");
excelMap.put("header",headerList);
//2.是否需要生成序号,序号从1开始(true-生成序号 false-不生成序)
boolean isSerial = false;
excelMap.put("isSerial",isSerial);
//3.sheet名
String sheetName = "统计表";
excelMap.put("sheetName",sheetName);
//4.需要放入Excel中的数据
Map<String,Object> map = new HashMap<>();
map.put("gender","男");
List<User> rows = userMapper.selectUserInfo(map);
List<List<String>> data= new ArrayList<>();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (User user:rows){
//所有的数据顺序必须和表头一一对应
//list存放每一行的数据(让所有的数据类型都转换成String,这样就无需担心Excel表格中数据不对)
List<String> list = new ArrayList<>();
list.add(String.valueOf(user.getId()));
list.add(String.valueOf(user.getUsername()));
list.add(String.valueOf(user.getGender()));
list.add(String.valueOf(user.getNationalId()));
list.add(String.valueOf(format.format(user.getCreateTime())));
//data存放全部的数据
data.add(list);
}
excelMap.put("data",data);
//Excel文件内容设置
HSSFWorkbook workbook = HandleFile.createExcel(excelMap);
String fileName = "导出excel例子.xls";
//生成excel文件
HandleFile.buildExcelFile(fileName, workbook);
//浏览器下载excel
HandleFile.buildExcelDocument(fileName,workbook,response);
return "down excel";
}
}
上述代码中:List<User> rows = userMapper.selectUserInfo(map);
数据内容是直接从数据库中查取的,具体实现较简单这里就不做代码详细展示。只展示下图数据库具体查询的内容
三、HandleFile工具类
public class HandleFile{
/**
* Excel内容设置
*
* @param excelMap
*/
public static HSSFWorkbook createExcel(Map<String, Object> excelMap) {
HSSFWorkbook workbook = new HSSFWorkbook();
String sheetName = excelMap.get("sheetName").toString();
HSSFSheet sheet = workbook.createSheet(sheetName);
//只考虑一个sheet的情况
HSSFRow row = sheet.createRow(0);
//设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
sheet.setColumnWidth(1, 12 * 256);
sheet.setColumnWidth(3, 17 * 256);
//表头设置为居中加粗
HSSFCellStyle style = workbook.createCellStyle();
HSSFFont font = workbook.createFont();
font.setBoldweight((short) 14);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
style.setFont(font);
//是否生成序号,序号从1开始
boolean isSerial = (boolean) excelMap.get("isSerial");
//获取表头列表
List<String> headerList = (List<String>) excelMap.get("header");
HSSFCell cell;
//生成表头
int headRow=0;
if (isSerial){
//设置第一个列为序号列
cell = row.createCell(0);
cell.setCellValue("序号");
cell.setCellStyle(style);
headRow = 1;
}
for (String header : headerList) {
cell = row.createCell(headRow);
cell.setCellValue(header);
cell.setCellStyle(style);
headRow++;
}
//往Excel中插入数据
List<List<String>> data = (List<List<String>>) excelMap.get("data");
int rowNum = 1;
//需要生成序号
if (isSerial){
//表头字段包含序号一列
int headSize = headerList.size() + 1;
for (List<String> obj:data){
HSSFRow currRow = sheet.createRow(rowNum);
for (int i=1;i<headSize;i++){
currRow.createCell(0).setCellValue(rowNum);
currRow.createCell(i).setCellValue(obj.get(i-1));
}
rowNum++;
}
//无需生成序号
}else{
int headSize = headerList.size();
for (List<String> obj:data){
HSSFRow currRow = sheet.createRow(rowNum);
for (int i=0;i<headSize;i++){
currRow.createCell(i).setCellValue(obj.get(i));
}
rowNum++;
}
}
return workbook;
}
/**
* 生成excel文件
*
* @param filename
* @param workbook
* @throws Exception
*/
public static void buildExcelFile(String filename, HSSFWorkbook workbook) throws Exception {
FileOutputStream fos = new FileOutputStream(filename);
workbook.write(fos);
fos.flush();
fos.close();
}
/**
* 浏览器下载excel
*
* @param filename
* @param workbook
* @param response
* @throws Exception
*/
public static void buildExcelDocument(String filename, HSSFWorkbook workbook, HttpServletResponse response) throws Exception {
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
}
}
四、测试结果
直接在浏览器中访问路径地址
五、下载的Excel文件