目的:Spring RESTful使用java POI导出数据库记录到Excel(包含图片)
环境:
win10 x64
Idea 2018.2.3
问题分析:
项目临时需要添加导出mysql数据记录到Excel的功能
解决方案:
使用Java POI包进行数据导出
方法步骤:
1. Pom文件中添加对于POI包依赖
<!-- POI套件 ver3.9-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
2. service和serviceImpl,导出示例:
CommonDataDealServiceImpl.class
@Override
public void outputPersonInfoToExcel(HttpServletResponse response){
/* 查询personInfo */
PersonExampl personExample = new PersonExample();
List<PersonExample> personList = personMapper.selectByExample(personExample);
/* 数据库无记录 */
if(personList.isEmpty()){
throw new CommonException(CommonMessage.NO_DATA);
}
/* 设置导出Excel信息 */
HSSFWorkbook workbook = new HSSFWorkbook(); // 创建workbook
HSSFSheet sheet = workbook.createSheet("人员记录"); // 创建sheet, 并设置sheet名
String fileName = "人员信息表.xls"; // 导出Excel文件名
String[] headers ={"姓名", "性别", "年龄", "头像"}; // Excel中表头
HSSFRow headerRow = sheet.createRow)(0); // 创建表头
for(int i = 0; i < headers.length; i ++){
HSSFCell cellTemp = headerRow.createCell(i);
HSSFRichTextString headerText = new HSSFRichTextString(header[i]);
cellTemp.setCellValue(headerText);
}
/* 插入数据 */
int rowNum = 1; //从第二行(表头下一行开始插入)
for(Person person : personList){
HSSFRow rowTemp = sheet.createRow(rowNum);
/* 按表头顺序插入姓名、性别、年龄 */
rowTemp.createCell(0).setCellValue(person.getName);
rowTemp.createCell(1).setCellValue(person.getSex);
rowTemp.createCell(2).setCellValue(person.getAge);
/* 插入头像图片 */
//下载图片(插入Excel需要byte[]形式的图片, 可自行获取)
byte[] imgBytes = localFileService.downloadFile(person.getImgPath);
if(image != null){ //如图片byte[]有效, 则执行插入图片到头像列
HSSFPatriarch drawingPatriarch = sheet.createDrawingPatriarch();
/** anchor主要用于设置图片的属性, 这里详细说明下HSSFClientAnchor的参数
* HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)
* dx1 左上角所在cell的偏移x坐标,一般可设0,范围值为:0~1023,超过1023就到右侧相邻的单元格里
* dy1 左上角所在cell的偏移y坐标,一般可设0,范围值为:0~256,超过256就到下方的单元格里
* dx2 右下角所在cell的偏移x坐标,一般可设0,范围值为:0~1023,超过1023就到右侧相邻的单元格里
* dy2 右下角所在cell的偏移y坐标,一般可设0,范围值为:0~256,超过256就到下方的单元格里
* col1 左上角所在列
* row1 左上角所在行
* col2 右下角所在列
* row2 右下角所在行
* 综上: 如果图片较大, 会占据多行的多个cell, 那么就用图片所在的左上角的cell的cellNum和rowNum及图片右下角所在的cell的cellNum和rowNum来界定图片范围。
*
* 例: 假如人员头像占据区域是两行两列的4个cell, 下面写法需要如下(相应的循环里面的row自增时需要对应调整为 rowNum += 2):
* HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 3, rowNum, (short) 4, rowNum + 1);
*/
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 3, rowNum, (short) 3, rowNum);
HSSFPicture pict = drawingPatriarch.createPicture(anchor, workbook.addPicture(imgBytes, HSSFWorkbook.PICTURE_TYPE_PNG));
pict.resize(0.5); // 图片等比例缩小
sheet.setColumnWidth(3, (int) (50 + 0.72) * 256); // 设置列宽, 旧版本该函数参数类型为short
rowTemp.setHeight((short) 256); // 设置行高
}else{ //如未找到对应头像,则值设置为空
HSSFCell cellTemp = rowTemp.createCell(3);
cellTemp.setCellType(HSSFCell.CELL_TYPE_STRING);
cellTemp.setCellValue("无");
}
rowNum += 1;
}
/* 设置response的header */
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
response.setContentType("application/application/Vnd.ms-excel;charset=UTF-8");
try{
response.flushBuffer();
workbook.write(response.getOutputStream());
} catch (IOException e){
throw new BaseException(CommonMessage.RESPONSE_STREAM_ERROR);
}
}
3. Controller中RESTful
@ResponseBody
@RequestMapping(value = "/output/perosnInfo", method = RequestMethod.GET)
public void outputPersonInfo(HttpServletResponse response){
commonDataDealServiceImpl.outputPersonInfoToExcel(response);
}
4. 测试Html
<html>
<head>
<script>
function dowloadFile(){
window.location.href="http://localhost:8080/output/personInfo";
}
</script>
</head>
<body>
<table border="0" style="margin-top: 4px; margin-left: 18px">
<tr>
<td> <a href="#" class="easyui-linkbutton" onclick="dowloadFile();"> 数据导出 </a></td>
</tr>
</table>
</body>
</html>
Tips
1. row和cell的关系, 还有序号都是从0开始。
2. 设置列宽和行高的方法。
3. 如含有图片时, 注意计算好图片占据的行列(图片实际覆盖多少格), 然后设置HSSFClientAnchor。
4. 如若请求是POST,只是添加参数,流程类似GET
本文介绍如何在Spring RESTful应用中使用Java POI库将数据库记录导出为Excel文件,并且包含图片。首先,讨论了项目的需求背景,然后详细解释了解决方案的四个步骤:添加POI依赖、实现service和服务实现、定义Controller的REST接口以及创建测试HTML页面。
1436

被折叠的 条评论
为什么被折叠?



