| New file |
| | |
| | | package com.estate.expert.admin.stat.report.render; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.deepoove.poi.policy.DynamicTableRenderPolicy; |
| | | import com.deepoove.poi.util.TableTools; |
| | | import org.apache.poi.xwpf.usermodel.ParagraphAlignment; |
| | | import org.apache.poi.xwpf.usermodel.XWPFTable; |
| | | import org.apache.poi.xwpf.usermodel.XWPFTableCell; |
| | | import org.apache.poi.xwpf.usermodel.XWPFTableRow; |
| | | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; |
| | | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; |
| | | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.math.BigInteger; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 设备分组表格渲染策略:同一设备类型内合并类型和数量,设备类型变更时重新分组。 |
| | | */ |
| | | public class DeviceGroupTablePolicy extends DynamicTableRenderPolicy { |
| | | |
| | | private static final int TYPE_COL = 0; |
| | | private static final int COUNT_COL = 1; |
| | | private static final int NUMBER_COL = 2; |
| | | |
| | | @Override |
| | | public void render(XWPFTable table, Object data) { |
| | | var groups = (List<Object>) data; |
| | | int templateRowIndex = findTemplateRowIndex(table); |
| | | if (templateRowIndex < 0) { |
| | | return; |
| | | } |
| | | |
| | | table.removeRow(templateRowIndex); |
| | | if (CollectionUtils.isEmpty(groups)) { |
| | | return; |
| | | } |
| | | |
| | | int insertIndex = templateRowIndex; |
| | | int groupStart = templateRowIndex; |
| | | int groupSize = 0; |
| | | |
| | | for (Object item : groups) { |
| | | if (!(item instanceof JSONObject group)) { |
| | | continue; |
| | | } |
| | | |
| | | boolean firstRowOfGroup = StringUtils.hasText(group.getString("设备类型")); |
| | | XWPFTableRow row = table.insertNewTableRow(insertIndex++); |
| | | renderRow(row, group, firstRowOfGroup); |
| | | |
| | | if (firstRowOfGroup) { |
| | | mergeGroup(table, groupStart, groupSize); |
| | | groupStart = insertIndex - 1; |
| | | groupSize = 1; |
| | | } else { |
| | | groupSize++; |
| | | } |
| | | } |
| | | |
| | | mergeGroup(table, groupStart, groupSize); |
| | | } |
| | | |
| | | private int findTemplateRowIndex(XWPFTable table) { |
| | | for (int i = 0; i < table.getRows().size(); i++) { |
| | | if (rowText(table.getRow(i)).contains("[设备编号]")) { |
| | | return i; |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | private String rowText(XWPFTableRow row) { |
| | | if (row == null) { |
| | | return ""; |
| | | } |
| | | return row.getTableCells().stream() |
| | | .map(XWPFTableCell::getText) |
| | | .reduce("", String::concat); |
| | | } |
| | | |
| | | private void renderRow(XWPFTableRow row, JSONObject group, boolean firstRowOfGroup) { |
| | | renderCell(row, firstRowOfGroup ? group.getString("设备类型") : "", 2972); |
| | | renderCell(row, firstRowOfGroup ? group.getString("设备数量") : "", 1531); |
| | | renderCell(row, group.getString("设备编号"), 4706); |
| | | } |
| | | |
| | | private void renderCell(XWPFTableRow row, String text, int width) { |
| | | XWPFTableCell cell = row.createCell(); |
| | | var tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr(); |
| | | tcPr.addNewTcW().setW(BigInteger.valueOf(width)); |
| | | tcPr.getTcW().setType(STTblWidth.DXA); |
| | | tcPr.addNewGridSpan().setVal(BigInteger.valueOf(2)); |
| | | tcPr.addNewVAlign().setVal(STVerticalJc.CENTER); |
| | | |
| | | var borders = tcPr.addNewTcBorders(); |
| | | borders.addNewTop().setVal(STBorder.SINGLE); |
| | | borders.addNewBottom().setVal(STBorder.SINGLE); |
| | | borders.addNewLeft().setVal(STBorder.SINGLE); |
| | | borders.addNewRight().setVal(STBorder.SINGLE); |
| | | borders.getTop().setColor("000000"); |
| | | borders.getBottom().setColor("000000"); |
| | | borders.getLeft().setColor("000000"); |
| | | borders.getRight().setColor("000000"); |
| | | borders.getTop().setSz(BigInteger.valueOf(4)); |
| | | borders.getBottom().setSz(BigInteger.valueOf(4)); |
| | | borders.getLeft().setSz(BigInteger.valueOf(4)); |
| | | borders.getRight().setSz(BigInteger.valueOf(4)); |
| | | |
| | | var paragraph = cell.getParagraphs().get(0); |
| | | paragraph.setAlignment(ParagraphAlignment.CENTER); |
| | | var run = paragraph.createRun(); |
| | | run.setFontFamily("黑体"); |
| | | run.setFontSize(12); |
| | | run.setText(text == null ? "" : text); |
| | | cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); |
| | | } |
| | | |
| | | private void mergeGroup(XWPFTable table, int groupStart, int groupSize) { |
| | | if (groupSize <= 1) { |
| | | return; |
| | | } |
| | | TableTools.mergeCellsVertically(table, TYPE_COL, groupStart, groupStart + groupSize - 1); |
| | | TableTools.mergeCellsVertically(table, COUNT_COL, groupStart, groupStart + groupSize - 1); |
| | | } |
| | | } |