Codex Assistant
2025-11-06 375c18a6d2713ff19b22093eec57315992d8333f
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
package com.rongyichuang.review;
 
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.junit.jupiter.api.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
 
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
 
/**
 * 快速验证DOCX表格宽度与签字区域布局
 */
public class DocxLayoutTest {
 
    private void applyTableLayout(XWPFTable table, int[] colWidthsTwips) {
        CTTbl ctTbl = table.getCTTbl();
        CTTblPr tblPr = ctTbl.getTblPr() == null ? ctTbl.addNewTblPr() : ctTbl.getTblPr();
        CTTblWidth tblW = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        tblW.setType(STTblWidth.DXA);
        int total = 0;
        for (int w : colWidthsTwips) total += w;
        tblW.setW(BigInteger.valueOf(total));
 
        CTTblGrid grid = ctTbl.getTblGrid() == null ? ctTbl.addNewTblGrid() : ctTbl.getTblGrid();
        while (grid.sizeOfGridColArray() > 0) {
            grid.removeGridCol(0);
        }
        for (int w : colWidthsTwips) {
            CTTblGridCol col = grid.addNewGridCol();
            col.setW(BigInteger.valueOf(w));
        }
    }
 
    private void ensureCells(XWPFTableRow row, int cellCount) {
        int existing = row.getTableCells().size();
        for (int i = existing; i < cellCount; i++) {
            row.addNewTableCell();
        }
    }
 
    private void setCellText(XWPFTableCell cell, String text) {
        while (cell.getParagraphs().size() > 0) {
            cell.removeParagraph(0);
        }
        XWPFParagraph p = cell.addParagraph();
        p.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run = p.createRun();
        run.setFontSize(12);
        run.setText(text);
 
        CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
        CTTblWidth w = tcPr.isSetTcW() ? tcPr.getTcW() : tcPr.addNewTcW();
        w.setType(STTblWidth.DXA);
    }
 
    @Test
    public void generateSampleDoc() throws Exception {
        XWPFDocument doc = new XWPFDocument();
 
        XWPFParagraph title = doc.createParagraph();
        title.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun tr = title.createRun();
        tr.setText("评审评分表(布局验证)");
        tr.setBold(true);
        tr.setFontSize(18);
 
        XWPFTable table = doc.createTable();
        applyTableLayout(table, new int[]{6072, 1500, 1500});
        XWPFTableRow header = table.getRow(0);
        ensureCells(header, 3);
        setCellText(header.getCell(0), "评分项");
        setCellText(header.getCell(1), "得分");
        setCellText(header.getCell(2), "满分");
 
        for (int i = 1; i <= 5; i++) {
            XWPFTableRow row = table.createRow();
            ensureCells(row, 3);
            setCellText(row.getCell(0), "示例项目" + i);
            setCellText(row.getCell(1), String.valueOf(10 * i));
            setCellText(row.getCell(2), "100");
        }
 
        // 签字区
        XWPFParagraph spacer = doc.createParagraph();
        spacer.setSpacingBefore(200);
 
        XWPFTable signTable = doc.createTable(1, 2);
        applyTableLayout(signTable, new int[]{6500, 2572});
        XWPFTableRow row = signTable.getRow(0);
        ensureCells(row, 2);
        setCellText(row.getCell(0), "专家评审签字:_______________");
        setCellText(row.getCell(1), "签字日期:__________");
 
        File out = new File("d:/code/new-ryc/tmp/docx-layout-sample.docx");
        out.getParentFile().mkdirs();
        try (FileOutputStream fos = new FileOutputStream(out)) {
            doc.write(fos);
        }
        doc.close();
    }
}