本文已参与「新人创作礼」活动,一起开启掘金创作之路。
项目组要导出报表,本来是准备用stimulsoft报表,后来觉得模板的修改过于麻烦,需要专门的工具,决定使用word,excel之类的模板进行报表的打印。 本来使用Poi做了excel的导出,后来做word导出很不方便,网上找了EasyPoi,功能更加人性化,简化了开发细节。
1.pom文件的导入
<!--word导出相关 Poi和EasyPoi具有相同的功能 简化了poi的细节-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.0.0</version>
</dependency>
2.创建工具类ExcelUtils
public class ExcelUtils {
/**
* Excel表格导出
*
* @param response HttpServletResponse对象
* @param excelData Excel表格的数据,封装为List<List<String>>
* @param sheetName sheet的名字
* @param fileName 导出Excel的文件名
* @throws IOException 抛IO异常
*/
public static void exportExcel(HttpServletResponse response,
List<List<String>> excelData,
String sheetName,
String fileName) throws IOException {
//声明一个工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
//生成一个表格,设置表格名称
HSSFSheet sheet = workbook.createSheet(sheetName);
HSSFCellStyle setBorder = workbook.createCellStyle();
//添加通用的样式
setStyle(workbook,sheet,setBorder);
//写入List<List<String>>中的数据
int rowIndex = 0;
for (List<String> data : excelData) {
//创建一个row行,然后自增1
HSSFRow row = sheet.createRow(rowIndex++);
//遍历添加本行数据
for (int i = 0; i < data.size(); i++) {
//创建一个单元格
HSSFCell cell = row.createCell(i);
//创建一个内容对象
HSSFRichTextString text = new HSSFRichTextString(data.get(i));
//将内容对象的文字内容写入到单元格中
cell.setCellValue(text);
cell.setCellStyle(setBorder); //将设置的样式添加到excel
}
}
//准备将Excel的输出流通过response输出到页面下载
//八进制输出流
response.setContentType("application/octet-stream");
//设置导出Excel的名称
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
//刷新缓冲
response.flushBuffer();
//workbook将Excel写入到response的输出流中,供页面下载该Excel文件
workbook.write(response.getOutputStream());
//关闭workbook
workbook.close();
}
/**
* Excel表格样式设置
* @version [版本号, 2021-09-09 14:17:26]
* @author liutao
*/
private static void setStyle(HSSFWorkbook wb, HSSFSheet sheet, HSSFCellStyle setBorder) {
//设置背景色
// setBorder.setFillForegroundColor((short) 13);// 设置背景色
// setBorder.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//设置边框:
setBorder.setBorderBottom(BorderStyle.THIN);
//左边框
setBorder.setBorderLeft(BorderStyle.THIN);
//上边框
setBorder.setBorderTop(BorderStyle.THIN);
//右边框
setBorder.setBorderRight(BorderStyle.THIN);
//水平居中
setBorder.setAlignment(HorizontalAlignment.CENTER);
//上下居中
setBorder.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
setBorder.setWrapText(true);
//设置字体: 根据标题和内容不同设置不同字体
// HSSFFont font = wb.createFont();
// font.setFontName("黑体");
// font.setBold(isBold);;//粗体显示
// font.setFontHeightInPoints((short) 12);//设置字体大小
//
HSSFFont font2 = wb.createFont();
font2.setFontName("FangSong");
font2.setFontHeightInPoints((short) 12);
setBorder.setFont(font2);//选择需要用到的字体格式
//设置表格列宽度
sheet.setDefaultColumnWidth(25);
//设置列宽:
// sheet.setColumnWidth(0, 3766); //第一个参数代表列id(从0开始),第2个参数代表宽度值
//设置自动换行:
setBorder.setWrapText(true);//设置自动换行
}
}
setStyle是我自己找的一些样式,可以自己通过自己需要去网上添加样式属性,set进去就行。
3.编写Controller层
@RequestMapping(value="exportScheme",method=RequestMethod.GET)
@ApiOperation("轮巡方案导出测试演示,后续代码导出在自己的Controller调用工具类")
public R exportScheme(HttpServletRequest request,HttpServletResponse response){
List<TbPatrolScheme> patrolList = schemeService.getAllList();
String sheetName = "测试";
String fileName = "Scheme" + DateUtils.getDate("yyyyMMddHHmmss")+ ".xls";
try {
exportService.export(response,patrolList,sheetName,fileName);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return R.ok().message("导出成功");
}
patrolList 是我的业务数据,可以换成别的List<List>格式,后续处理更加方便。
4.Service编写
@Override
public void export(HttpServletResponse response, List<TbPatrolScheme> excelList, String sheetName, String fileName) throws IOException, IllegalAccessException {
List<List<String>> excelData = new ArrayList<>();
//设置表头
List<String> head = new ArrayList<>();
TbPatrolScheme e = new TbPatrolScheme();
//先通过class获得表头
Class cls = e.getClass();
Field[] fields = cls.getDeclaredFields();
for(int i=0; i<fields.length; i++){
Field f = fields[i];
f.setAccessible(true);
head.add(f.getName());
}
excelData.add(head);
for(TbPatrolScheme patrol : excelList){
//设置数据
List<String> data = new ArrayList<>();
for(int i=0; i<fields.length; i++){
Field f = fields[i];
f.setAccessible(true);
data.add(f.get(patrol).toString());
}
excelData.add(data);
}
ExcelUtils.exportExcel(response,excelData,sheetName,fileName);
}
excelData是需要导出的List<List数据格式,需要进行一些处理,我这边是先把实体类遍历,属性名先插入当作表头,再遍历业务数据进行工具类导出。
*编译成功后访问http:port/***exportScheme 就可以直接下载excel文档了