1.配置文件的准备
1.导出功能实现所需要的pom文件
<!-- 导出到word(循环图片) -->
<!-- word导出 方式:easypoi-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.4.0</version>
</dependency>
<!--注意:word中要使用循环等标签必须单独导入以下依赖-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.4</version>
</dependency>
这里需要注意的点!!!!!!!!!!!!!!!!!
easypoi的版本必须在4.3.0以上,否则在导出图片的时候,只会导出图片的内存地址,却不能显示出图片。
2.在配置目录下添加一个配置类
package com.state.grid.substation.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.Assert;
public class WordUtil {
public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
Assert.notNull(templatePath,"模板路径不能为空");
Assert.notNull(temDir,"临时文件路径不能为空");
Assert.notNull(fileName,"导出文件名不能为空");
Assert.isTrue(fileName.endsWith(".docx"),"word导出请使用docx格式");
if (!temDir.endsWith("/")){
temDir = temDir + File.separator;
}
File dir = new File(temDir);
if (!dir.exists()) {
dir.mkdirs();
}
try {
String userAgent = request.getHeader("user-agent").toLowerCase();
if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
}
XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
String tmpPath = temDir + fileName;
FileOutputStream fos = new FileOutputStream(tmpPath);
doc.write(fos);
// 设置强制下载不打开
response.setContentType("application/force-download");
// 设置文件名
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
OutputStream out = response.getOutputStream();
doc.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
delFileWord(temDir,fileName);//这一步看具体需求,要不要删
}
}
/**
* 删除零时生成的文件
*/
public static void delFileWord(String filePath, String fileName) {
File file = new File(filePath + fileName);
File file1 = new File(filePath);
file.delete();
file1.delete();
}
}
3.准备一个导出模板(固定位置填充固定数据,表格和图片的循环导出)
解释一下模板中所填充的东西:
1.像这种:用两个花括号括起来的变量名,到时候会将变量名所指代的数据填充进去
2.像这种:需要将批量数据循环导出的表格以及图片
2.功能的实现(写一个Controller)
调用service和mapper没写,具体以实际需求为准
1.先理一些这个功能实现的逻辑:
去数据库查表获取想要的信息----用一个集合将这些信息都装起来----将这些信息都插入到模板的指定位置当中去
2.功能的实现(带注释)
这个肯定不能直接拿来运行,注意看我写的注释,理解代码逻辑,我写的很清楚,每一行代码干了什么我都有写。
/**
* 巡视报告的导出(循环图片版)
* @param substationId
* @param calendarId
* @param request
* @param response
* @return
*/
//请求路径是/taskResultToWord,请求方式是get请求
@RequestMapping(value = "/taskResultToWord", method = RequestMethod.GET)
//返回Result类型,传进来变电站id,日历id
public Result taskResultToWord(String substationId, String calendarId, HttpServletRequest request, HttpServletResponse response) throws Exception { // 分页查询
int code = 0;
String msg = "";
// 定义List集合list,泛型是TaskResultEquipment
List<TaskResultEquipment> list = new ArrayList<>();
// List<TaskProgress> uplist = new ArrayList<>();
//定义Map集合resmap
// Map<String, Object> resmap = new HashMap<>();
try {
//token验证
Des3Util des = new Des3Util();
String token = request.getHeader("token");
String jsonUser = des.parseDES(token);
JSONObject jsonData = JSONObject.fromObject(jsonUser);
String userId = (String) jsonData.get("u");
String roleId = (String) jsonData.get("r");
boolean access = this.roleService.getAccess(roleId, "task/taskList");
if(access){
//定义Map集合map
Map<String, Object> map = new HashMap<>();
//将输入的设备id添加到map集合里面
// map.put("substationId", substationId);
//将输入的日历id添加到calendarId里面
map.put("calendarId", calendarId);
//返回表v_task_result_equipment中的数据条数
int count = this.taskService.taskResultEquipmentCount(map);
//将查询到的基本信息赋给taskProgress
TaskProgress taskProgress = this.taskService.taskResultInfo(map);
//添加字段startRow(开始行)的值为0
map.put("startRow", 0);
//添加字段endRow(结束行)的值为count,count的值就是表v_task_result_equipment中的数据条数
map.put("endRow", count);
//分页查询表v_task_result_equipment中的数据,起始行是0,结束行是count,就是一页查询所有数据,
list = this.taskService.taskResultEquipmentList(map);
System.out.println(list);
//路径
String path1 = ResourceUtils.getURL("classpath:").getPath();
String path2 = path1.substring(1);
String terminalType = System.getProperty("os.name");
String path = "";
if (Objects.equals(terminalType, "Linux")){
path = path1.replace("ROOT/WEB-INF/classes/", "").replace("ROOT\\WEB-INF\\classes\\", "");
}else {
path = path2.replace("ROOT/WEB-INF/classes/", "").replace("ROOT\\WEB-INF\\classes\\", "");
}
System.out.println("path!!!!!!" + path);
//PATH是文件导出路径resource/excel/
String PATH = path + config.getExportUrl();
//ImagePath是图片导入路径resource/cameraImage/
String ImagePath = path + config.getCameraImageUrl();
//导出表头信息
//定义一个Map集合params
Map<String, Object> params = new HashMap<>();
//模板文件的路径templatePath
String templatePath = "E:/template/patrolWord.docx"; //模板路径
//简单渲染文本
params.put("substationName", taskProgress.getSubstationName());
params.put("voltageLevel", taskProgress.getVoltageLevel());
params.put("viewStartTime",taskProgress.getViewStartTime());
params.put("patrolType",taskProgress.getPatrolType());
params.put("taskName",taskProgress.getTaskName());
params.put("className",taskProgress.getClassName());
params.put("totalNumber",taskProgress.getTotalNumber());
params.put("execresult1",taskProgress.getExecresult1());
params.put("execresult2",taskProgress.getExecresult2());
params.put("execresult0",taskProgress.getExecresult0());
params.put("execresult3",taskProgress.getExecresult3());
params.put("execStartTime",taskProgress.getExecStartTime());
params.put("execEndTime",taskProgress.getExecEndTime());
//声明了一个名为alarms的变量,它是一个List类型,其中每个元素都是一个Map<String, Object>类型的键值对集合。
List<Map<String, Object>> alarms = new ArrayList<>();
//声明了一个名为alarm的变量,它是一个Map类型的键值对集合。具体来说,这个Map对象中每个键都是一个String类型,每个值都是一个Object类型。
Map<String, Object> alarm;
//会遍历list集合中的每个元素,并将每个元素赋值给循环变量taskResultEquipment。
// 在每次循环迭代中,可以使用taskResultEquipment变量来访问集合中当前元素的属性和方法。
//数据来源是摄像头
String source = "摄像头";
//序号从1开始
int order = 1;
for (TaskResultEquipment taskResultEquipment : list){
//img_path得到表中一行数据的图片路径
String img_path = taskResultEquipment.getPicture();
//ImagePath是图片导入路径resource/cameraImage/,realImagePath是图片真正的路径
String realImagePath = ImagePath + img_path;
//将图片路径打印出来
System.out.println(realImagePath);
// File imagefile = new File(realImagePath);
// if (imagefile.exists()){
// taskResultEquipment.setImageData(realImagePath);
// }else {
// String errorFile = ImagePath + config.getErrorCameraImageUrl();
// taskResultEquipment.setImageData(errorFile);
// }
//创建了一个名为alarm的新的HashMap对象
alarm = new HashMap<>();
//将循环中获取到的信息添加到集合里面
//变电站
// alarm.put("name", taskResultEquipment.getTaskName());
//设备名称
alarm.put("order",order);
alarm.put("equipmentInterval", taskResultEquipment.getEquipmentInterval());
alarm.put("equipmentName", taskResultEquipment.getEquipmentName());
alarm.put("equipmentPart",taskResultEquipment.getEquipmentPart());
alarm.put("pointName", taskResultEquipment.getPointName());
alarm.put("importance", taskResultEquipment.getImportance());
alarm.put("result", taskResultEquipment.getResult());
alarm.put("realAlarmLevel", taskResultEquipment.getRealAlarmLevel());
alarm.put("confirmUser", taskResultEquipment.getConfirmUser());
alarm.put("execStartTime", taskResultEquipment.getExecStartTime());
alarm.put("source",source);
//表格内循环添加图片(easypoi 4.3以后才支持,不然只能打印出ImageEntity的内存地址)
//创建了一个名为simage的新的ImageEntity对象,并将其赋值给simage变量。
// 具体来说,ImageEntity是一个Java类,用于表示一个图像实体,其中包含了图像的各种属性和数据。
ImageEntity simage = new ImageEntity();
simage.setHeight(50);
simage.setWidth(50);
//将图片的本地路径导入进去
simage.setUrl(realImagePath);
//将simage对象的类型设置为URL类型。
//该图像实体表示的是一个通过URL链接获取的远程图像,而不是一个本地存储的图像。
simage.setType(ImageEntity.URL);
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// simage.setData(out.toByteArray()); //字节流读取
//将图片添加进去
alarm.put("img", simage);
//alarms是一个里面元素都是map的list集合
alarms.add(alarm);
order = order + 1;
}
//Map集合params,将jobs(元素为map的list集合添加进去)
params.put("alarms", alarms);
//定义了一个表示模板文件夹路径的字符串变量temDir,用于存储模板文件所在的文件夹的路径。
// 在这个例子中,temDir指向E:/template/file/word/路径。表示文件路径分隔符,可以是\或者/,具体取决于操作系统
String temDir="E:/template/" + File.separator + "file/word/"; ;//生成临时文件存放地址
//生成文件名
Long time = new Date().getTime();
// 生成的word格式
String formatSuffix = ".docx";
// 拼接后的文件名
String fileName = time + formatSuffix;//文件名 带后缀
//导出word
WordUtil.exportWord(templatePath, temDir, fileName, params, request, response);
// WordUtil.exportWord(templatePath, PATH, fileName, params, request, response);
code = 1;
}else{
msg = "token无效";
}
}catch (Exception e){
msg = "操作失败";
}
return Result.success(code, msg,null);
}
3.导出的效果
1.固定信息部分:
2.循环表格和循环图片部分