poi生成word固定表格列宽

一、需求

根据数据库生成文档,文档包含大量表格,表格数量不确定,每个表格行数也不确定。

二、实现方案

引入依赖
xml 复制代码
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>ooxml-schemas</artifactId>
    <version>1.4</version>
</dependency>
代码实现
  1. 静态常量

    java 复制代码
    public static final int FONT_SIZE = 9;
    public static final TitleStyle[] titleStyles = {
            new TitleStyle("一级标题", 44, true),
            new TitleStyle("二级标题", 36, true),
            new TitleStyle("三级标题", 32, true),
            new TitleStyle("四级标题", 30, false)};
            
    public record TitleStyle(String name, int fontSize, boolean bold) {
    
    }
  2. 创建文档

    java 复制代码
    /**
     * A3 Portrait  16840 23814 720
     * A3 Landscape 23814 16940 720
     * A4 Portrait  11907 16840 720
     * A4 Landscape 16840 11907 720
     */
    public void createDocument(int width, int height, int top, int right, int bottom, int left) {
        XWPFDocument document = new XWPFDocument();
        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
    
        CTPageSz pageSz = sectPr.addNewPgSz();
        pageSz.setW(BigInteger.valueOf(width));
        pageSz.setH(BigInteger.valueOf(height));
        pageSz.setOrient(width > height ? STPageOrientation.LANDSCAPE : STPageOrientation.PORTRAIT);
    
        CTPageMar pageMar = sectPr.addNewPgMar();
        pageMar.setTop(BigInteger.valueOf(top));
        pageMar.setRight(BigInteger.valueOf(right));
        pageMar.setBottom(BigInteger.valueOf(bottom));
        pageMar.setLeft(BigInteger.valueOf(left));
    
        for (int i = 0; i < titleStyles.length; i++) {
            addCustomHeadingStyle(document, titleStyles[i], i + 1);
        }
    }
    
    private static void addCustomHeadingStyle(XWPFDocument document, TitleStyle titleStyle, int headingLevel) {
        CTStyle ctStyle = CTStyle.Factory.newInstance();
        ctStyle.setStyleId(titleStyle.name());
    
        CTString styleName = CTString.Factory.newInstance();
        styleName.setVal(titleStyle.name());
        ctStyle.setName(styleName);
    
        CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
        indentNumber.setVal(BigInteger.valueOf(headingLevel));
        // lower number > style is more prominent in the formats bar
        ctStyle.setUiPriority(indentNumber);
    
        CTOnOff onOffNull = CTOnOff.Factory.newInstance();
        ctStyle.setUnhideWhenUsed(onOffNull);
        // style shows up in the formats bar
        ctStyle.setQFormat(onOffNull);
    
        // style defines a heading of the given level
        CTPPr ppr = CTPPr.Factory.newInstance();
        ppr.setOutlineLvl(indentNumber);
        ctStyle.setPPr(ppr);
    
        CTRPr rpr = CTRPr.Factory.newInstance();
        // font size
        CTHpsMeasure ctHpsMeasure = CTHpsMeasure.Factory.newInstance();
        ctHpsMeasure.setVal(BigInteger.valueOf(titleStyle.fontSize()));
        rpr.setSz(ctHpsMeasure);
        rpr.setSzCs(ctHpsMeasure);
        
        // fond bold
        if (titleStyle.bold()) {
            CTOnOff b = rpr.addNewB();
            b.setVal(STOnOff.TRUE);
        }
        
        ctStyle.setRPr(rpr);
    
        XWPFStyle style = new XWPFStyle(ctStyle);
        style.setType(STStyleType.PARAGRAPH);
    
        XWPFStyles styles = document.createStyles();
        styles.addStyle(style);
    }
  3. 创建标题

    java 复制代码
    public void createTitle(int level, int id, String title) {
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setStyle(titleStyles[level - 1].name());
        XWPFRun run = paragraph.createRun();
        run.setText(title);
    
        CTBookmark bookmark = paragraph.getCTP().addNewBookmarkStart();
        bookmark.setName("bm_" + id);
        bookmark.setId(BigInteger.valueOf(id));
        paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(id));
    }
  4. 创建表格

    java 复制代码
    public XWPFTable createTable(int width, TableTitle... titles) {
        XWPFTable table = document.createTable(1, titles.length);
        CTTblPr TblPr = table.getCTTbl().addNewTblPr();
        TblPr.addNewTblLayout().setType(STTblLayoutType.FIXED); // 布局固定,不随内容改变宽度
        CTTblWidth tblW = TblPr.isSetTblW() ? TblPr.getTblW() : TblPr.addNewTblW();
        tblW.setType(STTblWidth.DXA);
        tblW.setW(BigInteger.valueOf(width));
        // 表格边颜色
        CTTblBorders borders = TblPr.addNewTblBorders();
        tableBorderStyle(borders.addNewInsideH());
        tableBorderStyle(borders.addNewInsideV());
        tableBorderStyle(borders.addNewLeft());
        tableBorderStyle(borders.addNewRight());
        tableBorderStyle(borders.addNewTop());
        tableBorderStyle(borders.addNewBottom());
    
        XWPFTableRow row = table.getRow(0);
        for (int i = 0; i < titles.length; i++) {
            TableTitle title = titles[i];
            XWPFTableCell cell = row.getCell(i);
            cell.setColor("3a60a0");
            if (title.width() > 0) {
                CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
                CTTblWidth tblWidth = ctTcPr.isSetTcW() ? ctTcPr.getTcW() : ctTcPr.addNewTcW();
                tblWidth.setW(BigInteger.valueOf(title.width()));
                tblWidth.setType(STTblWidth.DXA);
            }
            XWPFParagraph paragraphArray = cell.getParagraphArray(0);
            XWPFRun run = paragraphArray.createRun();
            run.setText(title.name());
            run.setBold(true);
            run.setColor("f5f5f5a");
            run.setFontSize(FONT_SIZE);
            paragraphArray.setAlignment(ParagraphAlignment.CENTER); // 水平居中
        }
        return table;
    }
    
    public record TableTitle(String name, int width) {
    
    }
  5. 创建空行

    java 复制代码
    public void createBlankLine() {
        document.createParagraph();
    }
  6. 创建表格行

    java 复制代码
    XWPFTableRow row = table.createRow();
  7. 获取单元格

    java 复制代码
    XWPFTableCell cell = row.getCell(0);
  8. 创建超链接

    java 复制代码
    public static void createHyperlinkRunToAnchor(XWPFParagraph paragraph, String text, int id) {
        paragraph.setVerticalAlignment(TextAlignment.CENTER);
        CTHyperlink ctHyperlink = paragraph.getCTP().addNewHyperlink();
        ctHyperlink.setAnchor("bm_" + id);
        ctHyperlink.addNewR();
        XWPFHyperlinkRun hyperlinkRun = new XWPFHyperlinkRun(ctHyperlink, ctHyperlink.getRArray(0), paragraph);
        hyperlinkRun.setText(text);
        hyperlinkRun.setColor("0000FF");
        hyperlinkRun.setUnderline(UnderlinePatterns.SINGLE);
        hyperlinkRun.setFontSize(FONT_SIZE);
    }
    
    public static void createHyperlinkRunToFile(XWPFParagraph paragraph, String text, String fileName, Integer id) {
        paragraph.setVerticalAlignment(TextAlignment.CENTER);
        String uri = fileName;
        if (id != null) {
            uri += "#bm_" + id;
        }
        String rId = paragraph.getDocument().getPackagePart()
                .addExternalRelationship(uri, XWPFRelation.HYPERLINK.getRelation()).getId();
        CTHyperlink ctHyperlink = paragraph.getCTP().addNewHyperlink();
        ctHyperlink.setId(rId);
        ctHyperlink.addNewR();
        XWPFHyperlinkRun hyperlinkRun = new XWPFHyperlinkRun(ctHyperlink, ctHyperlink.getRArray(0), paragraph);
        hyperlinkRun.setText(text);
        hyperlinkRun.setColor("0000FF");
        hyperlinkRun.setUnderline(UnderlinePatterns.SINGLE);
        hyperlinkRun.setFontSize(FONT_SIZE);
    }
相关推荐
乘风归趣3 小时前
spire.doc在word中生成公式
java·开发语言·word
爱转呼啦圈的小兔子4 小时前
Mac中修改Word的Normal.dotm文件
macos·word
传奇开心果编程4 小时前
【传奇开心果系列】Flet框架实现的图形化界面的PDF转word转换器办公小工具自定义模板
前端·python·学习·ui·前端框架·pdf·word
我命由我123453 天前
Excel 表格 - 合并单元格、清除单元格格式
运维·word·powerpoint·excel·工具·表格·软件工具
小付同学呀3 天前
word——如何给封面、目录、摘要、正文设置不同的页码
word
Quz3 天前
使用VBA宏批量修改Word中表格题注格式
word
PythonFun4 天前
基于Python的Word文件翻译器(免费下载)
word
修昔底德4 天前
一个适用于 Word(Mac/Win 通用) 的 VBA 宏:把所有“上角标格式的 0‑9”以及 “Unicode 上角标数字 ⁰‑⁹” 批量删除。
word
喝过期的拉菲6 天前
word参考文献对齐
word