许鹏程
2023-06-29 69da583c3a1ebb923c5023c5e2b42f094ccb1b53
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package com.product.print.util;
 
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.util.TableTools;
import com.product.common.lang.StringUtils;
import com.product.core.exception.BaseException;
import com.product.print.config.CmnCode;
import org.apache.poi.xwpf.usermodel.*;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 * @Author cheng
 * @Date 2023/6/27 15:50
 * @Desc
 */
public class DynamicTableRenderPolicy extends com.deepoove.poi.policy.DynamicTableRenderPolicy {
 
    private String replaceKey;
 
    private final String indexKey = "~index~";
 
    public DynamicTableRenderPolicy(String replaceKey) {
        this.replaceKey = replaceKey;
 
    }
 
    private XWPFRun run;
 
    @Override
    public void doRender(RenderContext<Object> context) throws Exception {
        RunTemplate runTemplate = (RunTemplate) context.getEleTemplate();
        XWPFRun run = runTemplate.getRun();
        try {
            if (!TableTools.isInsideTable(run)) {
                throw new IllegalStateException(
                        "The template tag " + runTemplate.getSource() + " must be inside a table");
            }
            XWPFTableCell cell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();
            XWPFTable table = cell.getTableRow().getTable();
            render(table, context.getData());
        } catch (Exception e) {
            throw new RenderException("Dynamic render table error:" + e.getMessage(), e);
        }
    }
 
    @Override
    public void render(XWPFTable xwpfTable, Object data) throws Exception {
        if (xwpfTable == null) {
            return;
        }
        List<Map<String, Object>> subTableData = (List<Map<String, Object>>) data;
        List<XWPFTableRow> rows = xwpfTable.getRows();
        //读取rows中的内容
        //获取最后一行
        XWPFTableRow xwpfTableRow = rows.get(rows.size() - 1);
        String tableExpression = "{{" + this.replaceKey + "}}";
        //获取表格起始行和结束行
        int startRowIndex = -1;
        int endRowIndex = -1;
        rows:
        for (int i = 0; i < rows.size(); i++) {
            XWPFTableRow row = rows.get(i);
            for (int j = 0; j < row.getTableCells().size(); j++) {
                if (startRowIndex > -1 && endRowIndex > -1) {
                    break rows;
                }
                XWPFTableCell cell = row.getTableCells().get(j);
                String text = cell.getText();
                if (tableExpression.equals(text)) {
                    startRowIndex = i;
                }
                if ("{{$~end~}}".equals(text)) {
                    endRowIndex = i;
                }
 
            }
        }
        //表格起始行不在第一行且没有找到结束标记
        if (startRowIndex > 0 && endRowIndex == -1) {
            throw new BaseException(CmnCode.NOT_FIND_END_FLAG);
        }
 
        if (startRowIndex == 0 && endRowIndex > 0) {
            //删除结束标记所在行
            xwpfTable.removeRow(endRowIndex);
        }
 
        //读取最后行每个单元格的值,调用getReplaceKey方法获取表达式中的值
        String[] fieldNames = new String[xwpfTableRow.getTableCells().size()];
//        for (int i = 0; i < xwpfTableRow.getTableCells().size(); i++) {
//            XWPFTableCell cell = xwpfTableRow.getTableCells().get(i);
//            String text = cell.getText();
//            String replaceKey = getReplaceKey(text);
//            //获取表达式中的值
//            if (StringUtils.isEmpty(replaceKey)) {
//                //设置单元格为空值
//                replaceKey = "";
//            }
//            fieldNames[i] = replaceKey;
//        }
//        //读取完毕后删除最后一行
//        xwpfTable.removeRow(rows.size() - 1);
        //获取所有的行判断单元格是否有值没有就删除该行
//        List<XWPFTableRow> tableRows = xwpfTable.getRows();
//        List<XWPFTableRow> deleteRows = new ArrayList<>();
//        for (int i = 0; i < tableRows.size(); i++) {
//            XWPFTableRow row = tableRows.get(i);
//            boolean flag = false;
//            for (int j = 0; j < row.getTableCells().size(); j++) {
//                XWPFTableCell cell = row.getTableCells().get(j);
//                if (StringUtils.isNotEmpty(cell.getText())) {
//                    flag = true;
//                    break;
//                }
//            }
//            if (!flag) {
//                deleteRows.add(row);
//            }
//        }
//        //遍历要删除的行获取所在的下标进行删除
//        for (int i = 0; i < deleteRows.size(); i++) {
//            XWPFTableRow row = deleteRows.get(i);
//            int index = xwpfTable.getRows().indexOf(row);
//            xwpfTable.removeRow(index);
//        }
//        //遍历数据集合,每个map对应一行数据
//        for (int i = 0; i < subTableData.size(); i++) {
//            Map<String, Object> map = subTableData.get(i);
//            //创建一行
//            XWPFTableRow row = xwpfTable.createRow();
//            //遍历字段每个字段创建一个单元格
//            for (int j = 0; j < fieldNames.length; j++) {
//                //当前单元格
//                XWPFTableCell cell;
//                //判断row中第j个单元格是否存在
//                if (row.getTableCells().size() > j) {
//                    cell = row.getTableCells().get(j);
//                } else {
//                    cell = row.createCell();
//                }
//                //设置单元格的值从map中取出
//                //判断是否是序号列
//                if (indexKey.equals(fieldNames[j])) {
//                    cell.setText(String.valueOf(i + 1));
//                    continue;
//                }
//                Object value = map.get(fieldNames[j]);
//                if (value == null) {
//                    value = "";
//                }
//                //设置单元格的值
//                cell.setText(value.toString());
//            }
//        }
 
    }
 
    /**
     * 解析表达式中的值获取 以{{$开头,以}}结尾的字符串取出$后面的值截止到}}
     */
    private String getReplaceKey(String text) {
        //使用正则解析表达式中的值获取 以{{$开头,以}}结尾的字符串取出$后面的值截止到}}
        Pattern pattern = Pattern.compile("\\{\\{\\$(.*?)\\}\\}");
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
}