Springboot 使用POI导出Excel文件

Springboot 使用POI导出Excel文件

本文使用 POI导出 xlsx后缀的Excel文件。

继上一次使用EasyExcel导出Excel文件实现功能后还有遗留问题,这次我试着用POI来重新实现,复刻EasyExcel导出文件的效果。

引入依赖

xml 复制代码
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>4.1.2</version>
</dependency>

逻辑处理

controller

@RestController
@Slf4j
@RequestMapping({"/v1/test"})
public class TestController {
    @Resource
    private TestService testService;

    @PostMapping("/export_record")
    public void exportRecord(HttpServletResponse response, @RequestBody GetRecordDto dto) {
        testService.exportRecord(response, dto);
        log.info("/export_record 导出记录完毕");
    }
}

service

数据查询

java 复制代码
@Override
public void exportRecord(HttpServletResponse response, GetRecordDto dto) {
	OutputStream out = null;
	try {
		XSSFWorkbook XSSFWorkbook = new XSSFWorkbook();
		// 查询数据
		List<GetRecordVo> recordInfoList = ...;
		// excel内容准备
		XSSFWorkbook = dataPrepare(recordVoPageInfo.getRecords());
		// 响应信息设置
		String fileName = UUID.randomUUID().toString().replace("-", "") + "_抓拍记录.xlsx" ;
		response.setContentType("application/OCTET-STREAM;charset=UTF-8");
		String file = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename=" + file);
		out = response.getOutputStream();
		XSSFWorkbook.write(out);
	}catch (MixException e){
		throw e;
	}catch (Exception e){
		log.error("导出记录失败:", e);
	} finally {
		IOUtils.closeQuietly(out);
	}
}

Excel文件内容处理

java 复制代码
private XSSFWorkbook dataPrepare(List<GetRecordVo> recordVoList) {
	XSSFWorkbook wb = new XSSFWorkbook();
	// 创建sheet
	XSSFSheet sheet1 = wb.createSheet("sheet1");
	// 设置表头行高
	short headHeight = 400;
	// 设置内容行高
	short contentHeight = 140;
	// 设置内容单元格居中样式
	CellStyle contentCenterStyle = getContentCenterStyle(wb);
	// 设置内容单元格左靠样式
	CellStyle contentLeftStyle = getContentLeftStyle(wb);
	// 设置标题单元格样式
	CellStyle headStyle = getHeadStyle(wb);
	// 创建表头
	XSSFRow row = sheet1.createRow(0);
	row.setHeight(headHeight);
	Cell cell = null;
	// 标题内容
	String[] headStr = {"序号", "时间", "照片", "姓名", "手机号码", "备注信息"};
	for(int i = 0; i < headStr.length; i++){
		cell = row.createCell(i);
		cell.setCellValue(headStr[i]);
		cell.setCellStyle(headStyle);
	}
	for (int i = 1; i < recordVoList.size() + 1; i++) {
		try {
			row = sheet1.createRow(i);
			row.setHeight((short) (100 * 70));
			row.setHeightInPoints(contentHeight);

			// 写入数据
			sheet1.setColumnWidth(0, 100 * 30);
			cell = row.createCell(0);
			cell.setCellValue(i);
			cell.setCellStyle(contentCenterStyle);

			sheet1.setColumnWidth(1, 100 * 70);
			cell = row.createCell(1);
			cell.setCellValue(recordVoList.get(i - 1).getAlarmTime());
			cell.setCellStyle(contentCenterStyle);

			sheet1.setColumnWidth(2, 100 * 50);
			cell = row.createCell(2);
			cell.setCellStyle(contentCenterStyle);

			byte[] faceImage = null;
			//画图的顶级管理器
			XSSFDrawing patriarch = sheet1.createDrawingPatriarch();
			//anchor主要用于设置图片的属性
			XSSFClientAnchor anchor = new XSSFClientAnchor(100000, 100000, -100000, -100000, (short) 3, i, (short) 3 + 1, i + 1);
			anchor.setAnchorType(ClientAnchor.AnchorType.byId(3));
			try {
				// 将图片转换成byte[]类型数据
				faceImage = ...;
				//插入图片
				if(ObjectUtils.isNotEmpty(faceImage)) {
					patriarch.createPicture(anchor, wb.addPicture(faceImage, Workbook.PICTURE_TYPE_JPEG));
				}
			} catch (Exception e) {
				log.error("=== log: getbyteArray timeout url: {} error:", recordVoList.get(i - 1).getFaceImageUrl(), e);
			}

			sheet1.setColumnWidth(3, 100 * 70);
			cell = row.createCell(3);
			cell.setCellValue(recordVoList.get(i - 1).getStaffName());
			cell.setCellStyle(contentLeftStyle);

			sheet1.setColumnWidth(4, 100 * 70);
			cell = row.createCell(4);
			cell.setCellValue(recordVoList.get(i - 1).getStaffPhone());
			cell.setCellStyle(contentCenterStyle);

			sheet1.setColumnWidth(5, 100 * 70);
			cell = row.createCell(5);
			cell.setCellValue(recordVoList.get(i - 1).getStaffRemark());
			cell.setCellStyle(contentLeftStyle);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 写入excel文件
	log.info("-------------------导出文件已经准备完毕---------------");
	return wb;
}

样式封装

java 复制代码
/**
 * 内容居中样式
 * @param wb
 * @return
 */
private CellStyle getContentCenterStyle(XSSFWorkbook wb){
	CellStyle contentCenterStyle = wb.createCellStyle();
	contentCenterStyle.setBorderBottom(BorderStyle.THIN);
	contentCenterStyle.setBorderLeft(BorderStyle.THIN);
	contentCenterStyle.setBorderRight(BorderStyle.THIN);
	contentCenterStyle.setBorderTop(BorderStyle.THIN);
	contentCenterStyle.setAlignment(HorizontalAlignment.CENTER);
	contentCenterStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	contentCenterStyle.setFont(getFontStyle(wb));
	return contentCenterStyle;
}

/**
 * 内容左靠样式
 * @param wb
 * @return
 */
private CellStyle getContentLeftStyle(XSSFWorkbook wb){
	CellStyle contentCenterStyle = wb.createCellStyle();
	contentCenterStyle.setBorderBottom(BorderStyle.THIN);
	contentCenterStyle.setBorderLeft(BorderStyle.THIN);
	contentCenterStyle.setBorderRight(BorderStyle.THIN);
	contentCenterStyle.setBorderTop(BorderStyle.THIN);
	contentCenterStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	contentCenterStyle.setFont(getFontStyle(wb));
	return contentCenterStyle;
}

/**
 * 标题居中样式
 * @param wb
 * @return
 */
private CellStyle getHeadStyle(XSSFWorkbook wb){
	CellStyle headStyle = wb.createCellStyle();
	headStyle.setBorderBottom(BorderStyle.THIN);
	headStyle.setBorderLeft(BorderStyle.THIN);
	headStyle.setBorderRight(BorderStyle.THIN);
	headStyle.setBorderTop(BorderStyle.THIN);
	headStyle.setAlignment(HorizontalAlignment.CENTER);
	headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	headStyle.setFont(getBoldFontStyle(wb));
	headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
	headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
	return headStyle;
}

/**
 * 普通文字样式
 * @param wb
 * @return
 */
private Font getFontStyle(XSSFWorkbook wb){
	Font contentFont = wb.createFont();
	contentFont.setFontName("仿宋");
	contentFont.setFontHeightInPoints((short) 12);
	return contentFont;
}

/**
 * 加粗文字样式
 * @param wb
 * @return
 */
private Font getBoldFontStyle(XSSFWorkbook wb){
	Font contentFont = wb.createFont();
	contentFont.setFontName("仿宋");
	contentFont.setFontHeightInPoints((short) 12);
	contentFont.setBold(true);
	return contentFont;
}

导出效果

  1. 【照片】列中的照片内边距已经设置成功
  2. 成功复刻上一篇使用EasyExcel导出的Excel文件

思考

  1. 为什么不导出.xls后缀的文件?
  2. POI导出与EasyExcel导出相比哪种方式最优呢?
  3. POI导出与EasyExcel导出两种方式有没有需要注意的坑呢?

这些问题我会在下一篇来详细解答。

相关推荐
《源码好优多》5 分钟前
基于Java Springboot汽配销售管理系统
java·开发语言·spring boot
kingbal10 分钟前
SpringCloud:Injection of resource dependencies failed
后端·spring·spring cloud
刘天远42 分钟前
django实现paypal订阅记录
后端·python·django
ℳ₯㎕ddzོꦿ࿐1 小时前
Spring Boot集成MyBatis-Plus:自定义拦截器实现动态表名切换
spring boot·后端·mybatis
逸风尊者1 小时前
开发也能看懂的大模型:RNN
java·后端·算法
尘浮生1 小时前
Java项目实战II基于Java+Spring Boot+MySQL的智能停车计费系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·微信小程序·maven
hai405872 小时前
Spring Boot整合Redis Stack构建本地向量数据库相似性查询
数据库·spring boot·redis
years_GG2 小时前
【Git多人开发与协作之团队的环境搭建】
spring boot·深度学习·vue·github·团队开发·个人开发
小钟不想敲代码3 小时前
第4章 Spring Boot自动配置
java·spring boot·后端
hummhumm3 小时前
第33章 - Go语言 云原生开发
java·开发语言·后端·python·sql·云原生·golang