POI操作Docx的踩坑指南(一)

Java的POI库是Apache软件基金会的一个开源项目,全称为Apache POI(Poor Obfuscation Implementation)。提供了Java操作Microsoft Office格式文件(如Word、Excel、PowerPoint等)的功能。

基本概念

Docx文档主要由文档(doc)、表格(table)、段落(paragraph)、运行(run)组成。

POI中表达对象表格:

中文描述 表达 POI对象
文档 doc XWPFDocument
表格 table XWPFTable
单元格 cell XWPFTableCell
段落 paragraph XWPFParagraph
段落中的一部分 run XWPFRun

XWPFDocument文档的常用方法

List<XWPFParagraph> getParagraphs():获取文档中所有的段落,注意表格中的段落不会包含在内。

List<XWPFTable> getTables():获取文档中所有的表格。

XWPFParagraph createParagraph():创建一个段落到文档最后。

XWPFParagraph insertNewParagraph(XmlCursor):插入一个段落到指定光标之前。

void write(OutputStream):将文档写入到一个输出流中。

XWPFParagraph段落的常用方法

XWPFRun createRun():在段落中创建一个新运行。

List<XWPFRun> getRuns():获取段落中所有的运行,获取到的运行列表是不可修改的。

String getText():获取段落的文本内容,包括所有运行的文本。

void setIndentationFirstLine(int indentation):设置段落的首行缩进。

void setAlignment(ParagraphAlignment align):设置段落的对齐方式。

void setSpacingBetween(double spacing):设置段落的多倍行距,注意固定值和多倍行距的设置有区别。

XWPFRun运行的常用方法

String text():获取运行的文本内容。

void setText(String value, int pos):设置运行的文本内容,pos是可选参数,如果要设置成空字符串,那pos则必须有。

void setFontSize(double size):设置字体大小。

常用操作

将某一个run替换为空字符串

java 复制代码
run.setText("",0);

复制段落字体大小

java 复制代码
int fontSize = oldParagraph.getRuns().get(0).getFontSize();
if (fontSize == -1 && oldParagraph.getStyle() != null) {
    // 从run中没有获取到字体大小
    XWPFStyle style = oldParagraph.getDocument().getStyles().getStyle(oldParagraph.getStyle());
    if (style != null && style.getCTStyle().isSetRPr()) {
        CTHpsMeasure sz = style.getCTStyle().getRPr().getSz();
        fontSize = sz.getVal().intValue() / 2;
    }
}
if(fontSize != -1){
    newParagraph.getRuns().get(0).setFontSize(fontSize);
}

复制段落行高以及段前后间距

java 复制代码
// 获取旧段落的CTPPr来操作行高
CTSpacing oldSpacing = oldParagraph.getCTP().getPPr().getSpacing();

if (oldSpacing != null) {
    CTSpacing newSpacing = newParagraph.getCTP().getPPr().isSetSpacing() ?
            newParagraph.getCTP().getPPr().getSpacing() :
               newParagraph.getCTP().getPPr().addNewSpacing();

    // 如果旧段落有固定行高设置,将其复制到新段落
    if (oldSpacing.isSetLine()) {
        newSpacing.setLine(oldSpacing.getLine());
        newSpacing.setLineRule(oldSpacing.getLineRule()); // 确保行高规则也复制
    }

    // 复制间距前后设置
    if (oldSpacing.isSetBefore()) {
        newSpacing.setBefore(oldSpacing.getBefore());
    }
    if (oldSpacing.isSetAfter()) {
        newSpacing.setAfter(oldSpacing.getAfter());
    }
}else{
    newParagraph.setSpacingBetween(oldParagraph.getSpacingBetween());
}

字体、文本颜色等需要根据自己需求添加进去。

相关推荐
小羊没烦恼!16 小时前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里17 小时前
java中的继承和多态的区别
java
小羊没烦恼!17 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕17 小时前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码17 小时前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖17 小时前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时17 小时前
01-06-A-JVM排查实战详解
java·jvm
vipxieliang18 小时前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
ba_pi18 小时前
mysql 查询所有表名并授权
java
ProcessOn官方账号18 小时前
java函数式编程--入门基础
java·编程·函数式编程