赞
踩
最近遇到html转word的需求,遍寻全网没找到简单易用的demo,于是打算自己写一个
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.10.RELEASE</version>
- <relativePath/>
- </parent>
依赖如下:
- <!-- 增加poi-tl依赖-->
- <dependency>
- <groupId>com.deepoove</groupId>
- <artifactId>poi-tl</artifactId>
- <version>1.10.4</version>
- </dependency>
其他依赖(仅供参考)
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-websocket</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>log4j-to-slf4j</artifactId>
- <groupId>org.apache.logging.log4j</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.16</version>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.5.1</version>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-generator</artifactId>
- <version>3.5.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.velocity</groupId>
- <artifactId>velocity-engine-core</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- <version>2.7.0</version>
- </dependency>
接口如下:
- /**
- * 导出word
- */
- @PostMapping("patrolRecordReport")
- public void patrolRecordReport(@RequestBody IdDTO idDTO, HttpServletResponse response)
- {
- recordService.patrolRecordReport(response, idDTO.getId());
- }
Service如下:
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.deepoove.poi.XWPFTemplate;
- import com.deepoove.poi.config.Configure;
- import com.deepoove.poi.data.PictureRenderData;
- import com.deepoove.poi.data.Pictures;
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.stereotype.Service;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.*;
- import java.util.stream.Collectors;
-
- @Service
- public class RecordService {
- private final INsjDeviceValueInfoService deviceValueInfoService;
- private final INsjPatrolRecordService patrolRecordService;
- private final INsjPatrolRecordPointValueService recordPointValueService;
- private final INsjPatrolPointInfoService patrolPointInfoService;
- private final INsjDeviceInfoService deviceInfoService;
- private final INsjPatrolInfoService patrolInfoService;
- private final INsjPatrolRecordPointService recordPointService;
-
- public RecordService(INsjDeviceValueInfoService deviceValueInfoService, INsjPatrolRecordService patrolRecordService, INsjPatrolRecordPointValueService recordPointValueService, INsjPatrolPointInfoService patrolPointInfoService, INsjDeviceInfoService deviceInfoService, INsjPatrolInfoService patrolInfoService, INsjPatrolRecordPointService recordPointService) {
- this.deviceValueInfoService = deviceValueInfoService;
- this.patrolRecordService = patrolRecordService;
- this.recordPointValueService = recordPointValueService;
- this.patrolPointInfoService = patrolPointInfoService;
- this.deviceInfoService = deviceInfoService;
- this.patrolInfoService = patrolInfoService;
- this.recordPointService = recordPointService;
- }
-
- //获取导出word要用到数据源map
- public Map<String, Object> getData(String id) {
- Map<String, Object> dataMap = new HashMap<>();
- List<PatrolRecordReportVO> patrolRecordReportVOS = new ArrayList<>();
-
- NsjPatrolRecord patrolRecord = patrolRecordService.getById(id);//任务记录
-
- List<NsjPatrolPointInfo> pointInfos = patrolPointInfoService.list(
- new QueryWrapper<NsjPatrolPointInfo>().eq("patrol_id", patrolRecord.getPatrolId()));
- Map<Long, String> pointMap = pointInfos.stream().collect
- (Collectors.toMap(NsjPatrolPointInfo::getId, NsjPatrolPointInfo::getName));
- List<NsjDeviceValueInfo> deviceValueInfos = deviceValueInfoService.list();
- Map<Long, String> deviceValueMap = deviceValueInfos.stream().collect
- (Collectors.toMap(NsjDeviceValueInfo::getId, NsjDeviceValueInfo::getName));
- Map<Long, Integer> dataTypeMap = deviceValueInfos.stream().collect
- (Collectors.toMap(NsjDeviceValueInfo::getId, NsjDeviceValueInfo::getDataType));
- List<NsjPatrolRecordPointValue> recordPointValues = recordPointValueService.list(
- new QueryWrapper<NsjPatrolRecordPointValue>().eq("record_id", id).orderByAsc("device_id"));
- List<NsjDeviceInfo> nsjDeviceInfos = deviceInfoService.list();//多个设备
- Map<Long, String> deviceMap = nsjDeviceInfos.stream().collect
- (Collectors.toMap(NsjDeviceInfo::getId, NsjDeviceInfo::getName));
- List<NsjPatrolRecordPoint> recordPoints = recordPointService.list();//多个点
- Map<Long, String> recordPointsMap = recordPoints.stream().collect
- (Collectors.toMap(NsjPatrolRecordPoint::getPointId, NsjPatrolRecordPoint::getCapture));
-
- for (int i = 0; i < recordPointValues.size(); i++) {
- NsjPatrolRecordPointValue recordPointValue = recordPointValues.get(i);
- PictureRenderData img = null;
- if (i != 0) {
- NsjPatrolRecordPointValue recordPointValue1 = recordPointValues.get(i - 1);
- if (!recordPointValue.getPointId().equals(recordPointValue1.getPointId())) {
- img = Pictures.ofLocal(recordPointsMap.get(recordPointValue.getPointId())).fitSize().create();
- }
- } else {
- img = Pictures.ofLocal(recordPointsMap.get(recordPointValue.getPointId())).fitSize().create();
- }
-
- PatrolRecordReportVO recordReportVO = new PatrolRecordReportVO(
- pointMap.get(recordPointValue.getPointId()), deviceMap.get(recordPointValue.getDeviceId()),
- deviceValueMap.get(recordPointValue.getValueId()), dataTypeMap.get(recordPointValue.getValueId()) == 1 ?
- recordPointValue.getValue().intValue() + "" : recordPointValue.getValue() + "", img);
- patrolRecordReportVOS.add(recordReportVO);
- }
-
- //获取名称,开始时间,结束时间
- NsjPatrolInfo patrolInfo = patrolInfoService.getById(patrolRecord.getPatrolId());
- //人员信息
- dataMap.put("list", patrolRecordReportVOS);
- dataMap.put("patrolName", patrolInfo.getName());
- dataMap.put("startTime", MyDateUtil.date2String(patrolRecord.getStartTime(), null));
- dataMap.put("endTime", MyDateUtil.date2String(patrolRecord.getEndTime(), null));
- return dataMap;
- }
-
- //导出word,返回文件流
- public void patrolRecordReport(HttpServletResponse response, String id) {
- Map<String, Object> dataMap = getData(id);
- //给需要单独处理的表格绑定处理策略
- Configure config = Configure.builder().bind("list", new DefineMethodPolicy()).build();
- InputStream input = null;
- try {
- input = new ClassPathResource("templates\\template.docx").getInputStream();
- } catch (IOException e) {
- e.printStackTrace();
- }
- XWPFTemplate template = XWPFTemplate.compile(input, config).render(dataMap);
- // 生成的word格式
- String formatSuffix = ".docx";
- // 拼接后的文件名
- String fileName = "GreenHouseGas" + formatSuffix;//文件名
- try {
- //=================生成word到设置浏览默认下载地址=================
- // 设置强制下载不打开
- response.setContentType("application/force-download");
- // 设置文件名
- response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
- OutputStream out = response.getOutputStream();
- template.write(out);
- out.flush();
- out.close();
- template.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
导出word及处理策略类如下:
- import com.deepoove.poi.XWPFTemplate;
- import com.deepoove.poi.data.RowRenderData;
- import com.deepoove.poi.data.Rows;
- import com.deepoove.poi.exception.RenderException;
- import com.deepoove.poi.policy.RenderPolicy;
- import com.deepoove.poi.render.compute.EnvModel;
- import com.deepoove.poi.render.compute.RenderDataCompute;
- import com.deepoove.poi.render.processor.DocumentProcessor;
- import com.deepoove.poi.render.processor.EnvIterator;
- import com.deepoove.poi.resolver.TemplateResolver;
- import com.deepoove.poi.template.ElementTemplate;
- import com.deepoove.poi.template.MetaTemplate;
- import com.deepoove.poi.template.run.RunTemplate;
- import com.deepoove.poi.util.ReflectionUtils;
- import com.deepoove.poi.util.TableTools;
- import org.apache.poi.xwpf.usermodel.*;
- import org.apache.xmlbeans.XmlCursor;
- import org.apache.xmlbeans.XmlObject;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
- import org.springframework.util.CollectionUtils;
-
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
-
- /**
- * @Description
- * @Author admin
- */
- public class DefineMethodPolicy implements RenderPolicy {
- private String prefix;
- private String suffix;
- private boolean onSameLine;
-
- public DefineMethodPolicy() {
- this(false);
- }
-
- public DefineMethodPolicy(boolean onSameLine) {
- this("[", "]", onSameLine);
- }
-
- public DefineMethodPolicy(String prefix, String suffix) {
- this(prefix, suffix, false);
- }
-
- public DefineMethodPolicy(String prefix, String suffix, boolean onSameLine) {
- this.prefix = prefix;
- this.suffix = suffix;
- this.onSameLine = onSameLine;
- }
-
- @Override
- public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
- RunTemplate runTemplate = (RunTemplate) eleTemplate;
- XWPFRun run = runTemplate.getRun();
-
- try {
- if (!TableTools.isInsideTable(run)) {
- throw new IllegalStateException("The template tag " + runTemplate.getSource() + " must be inside a table");
- } else {
- XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();
- XWPFTable table = tagCell.getTableRow().getTable();
- run.setText("", 0);
- int templateRowIndex = this.getTemplateRowIndex(tagCell);
- if (null != data && data instanceof Iterable) {
- Iterator<?> iterator = ((Iterable) data).iterator();
- XWPFTableRow templateRow = table.getRow(templateRowIndex);
- TemplateResolver resolver = new TemplateResolver(template.getConfig().copy(this.prefix, this.suffix));
- boolean firstFlag = true;
- int index = 0;
- boolean hasNext = iterator.hasNext();
-
- while (hasNext) {
- Object root = iterator.next();
- hasNext = iterator.hasNext();
- int insertPosition = templateRowIndex++;
- table.insertNewTableRow(insertPosition);
- this.setTableRow(table, templateRow, insertPosition);
- XmlCursor newCursor = templateRow.getCtRow().newCursor();
- newCursor.toPrevSibling();
- XmlObject object = newCursor.getObject();
- XWPFTableRow nextRow = new XWPFTableRow((CTRow) object, table);
- if (!firstFlag) {
- List<XWPFTableCell> tableCells = nextRow.getTableCells();
- Iterator var21 = tableCells.iterator();
-
- while (var21.hasNext()) {
- XWPFTableCell cell = (XWPFTableCell) var21.next();
- CTTcPr tcPr = TableTools.getTcPr(cell);
- CTVMerge vMerge = tcPr.getVMerge();
- if (null != vMerge && STMerge.RESTART == vMerge.getVal()) {
- vMerge.setVal(STMerge.CONTINUE);
- }
- }
- } else {
- firstFlag = false;
- }
-
- this.setTableRow(table, nextRow, insertPosition);
- RenderDataCompute dataCompute = template.getConfig().getRenderDataComputeFactory().
- newCompute(EnvModel.of(root, EnvIterator.makeEnv(index++, hasNext)));
- List<XWPFTableCell> cells = nextRow.getTableCells();
- cells.forEach((cellx) -> {
- List<MetaTemplate> templates = resolver.resolveBodyElements(cellx.getBodyElements());
- (new DocumentProcessor(template, resolver, dataCompute)).process(templates);
- });
- }
- }
-
- table.removeRow(templateRowIndex);
- this.afterloop(table, data);
- }
- } catch (Exception var25) {
- throw new RenderException("HackLoopTable for " + eleTemplate + "error: " + var25.getMessage(), var25);
- }
- }
-
- private int getTemplateRowIndex(XWPFTableCell tagCell) {
- XWPFTableRow tagRow = tagCell.getTableRow();
- return this.onSameLine ? this.getRowIndex(tagRow) : this.getRowIndex(tagRow) + 1;
- }
-
- protected void afterloop(XWPFTable table, Object data) {
- if (null == data) {
- return;
- }
- List<PatrolRecordReportVO> defineMethodList = null;
- try {
- defineMethodList = (List<PatrolRecordReportVO>) data;
- } catch (Exception e) {
- e.printStackTrace();
- }
- Map<String, List<PatrolRecordReportVO>> unitDefineMethodMap = defineMethodList.stream().collect(Collectors.groupingBy(PatrolRecordReportVO::getPoint));
- Map<String, List<PatrolRecordReportVO>> unitParamMap = defineMethodList.stream().collect(Collectors.groupingBy(defineMethod -> defineMethod.getPoint() + "-" + defineMethod.getDevice()));
- if (!CollectionUtils.isEmpty(defineMethodList)) {
- List<RowRenderData> dataList = new ArrayList<>();
- for (PatrolRecordReportVO tmp : defineMethodList) {
- RowRenderData renderData = Rows.create(tmp.getPoint(), tmp.getDevice(), tmp.getDeviceValue(), tmp.getValue().toString());
- dataList.add(renderData);
- }
- List<String> unitList = null;
- try {
- unitList = JacksonUtils.json2list(JacksonUtils.obj2json(unitDefineMethodMap.keySet()), String.class);
- } catch (Exception e) {
- e.printStackTrace();
- }
- List<String> paramList = null;
- try {
- paramList = JacksonUtils.json2list(JacksonUtils.obj2json(unitParamMap.keySet()), String.class);
- } catch (Exception e) {
- e.printStackTrace();
- }
- //处理合并
- for (int i = 0; i < dataList.size(); i++) {
- //处理第一列合并
- Object v = dataList.get(i).getCells().get(0).getParagraphs().get(0).getContents().get(0);
- String unit_name = String.valueOf(v);
- for (int j = 0; j < unitList.size(); j++) {
- String unitId = unitList.get(j);
- List<PatrolRecordReportVO> patrolRecordReportVOS = unitDefineMethodMap.get(unitId);
- String unitName = patrolRecordReportVOS.get(0).getPoint();
- if (unit_name.equals(unitName) && patrolRecordReportVOS.size() > 1) {
- // 合并第0列的第i+1行到第i+unitSize行的单元格
- TableTools.mergeCellsVertically(table, 0, i + 1, i + patrolRecordReportVOS.size());
- TableTools.mergeCellsVertically(table, 4, i + 1, i + patrolRecordReportVOS.size());
- //处理垂直居中
- for (int y = 0; y < 5; y++) {
- XWPFTableCell cell = table.getRow(i + 2).getCell(y);
- cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); //垂直居中
- }
- unitList.remove(j);
- break;
- }
- }
- //处理第二列合并
- Object v1 = dataList.get(i).getCells().get(1).getParagraphs().get(0).getContents().get(0);
- String paramType = v + "-" + v1;
- for (int j = 0; j < paramList.size(); j++) {
- String key = paramList.get(j);
- List<PatrolRecordReportVO> tmpList = unitParamMap.get(key);
- String paramName = tmpList.get(0).getPoint() + "-" + tmpList.get(0).getDevice();
- if (paramType.equals(paramName) && tmpList.size() > 1) {
- // 合并第1列的第i+1行到第i+unitSize行的单元格
- TableTools.mergeCellsVertically(table, 1, i + 1, i + tmpList.size());
- //处理垂直居中
- for (int y = 0; y < 5; y++) {
- XWPFTableCell cell = table.getRow(i + 2).getCell(y);
- cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); //垂直居中
- }
- paramList.remove(j);
- break;
- }
- }
- }
- }
- }
-
- private void setTableRow(XWPFTable table, XWPFTableRow templateRow, int pos) {
- List<XWPFTableRow> rows = (List) ReflectionUtils.getValue("tableRows", table);
- rows.set(pos, templateRow);
- table.getCTTbl().setTrArray(pos, templateRow.getCtRow());
- }
-
- private int getRowIndex(XWPFTableRow row) {
- List<XWPFTableRow> rows = row.getTable().getRows();
- return rows.indexOf(row);
- }
- }
word模板如下:
名称:{{patrolName}}
开始时间:{{startTime}}
结束时间:{{endTime}}
{{list}}点位 | 设备 | 测量值 | 数据 | 图片 |
[point] | [device] | [deviceValue] | [value] | [@img] |
数据模型类如下:
- import com.deepoove.poi.data.PictureRenderData;
-
- public class PatrolRecordReportVO {
-
- private String point;//点位
- private String device;//设备
- private String deviceValue;//测量值
- private String value;//数据
-
- private PictureRenderData img;//图片
-
- public PatrolRecordReportVO() {
- }
-
- public PatrolRecordReportVO(String point, String device, String deviceValue, String value, PictureRenderData img) {
- this.point = point;
- this.device = device;
- this.deviceValue = deviceValue;
- this.value = value;
- this.img = img;
- }
-
- public String getPoint() {
- return point;
- }
-
- public void setPoint(String point) {
- this.point = point;
- }
-
- public String getDevice() {
- return device;
- }
-
- public void setDevice(String device) {
- this.device = device;
- }
-
- public String getDeviceValue() {
- return deviceValue;
- }
-
- public void setDeviceValue(String deviceValue) {
- this.deviceValue = deviceValue;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public PictureRenderData getImg() {
- return img;
- }
-
- public void setImg(PictureRenderData img) {
- this.img = img;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。