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());
}

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

相关推荐
咖啡八杯14 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
SamDeepThinking1 天前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员
朕瞧着你甚好1 天前
技术雷达 & Java 集成评估报告 — Apache Tika 3.3.1
java·ai编程
MacroZheng1 天前
短短几天,暴涨2.8万Star!又一款编程神器开源!
java·人工智能·后端
SamDeepThinking1 天前
函数式编程:用BiFunction消除多类型分支的代码重复
java·后端·面试
Flittly2 天前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了2 天前
Java 生成二维码解决方案
java·后端
人活一口气2 天前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP2 天前
Vibe Coding -- 完整项目案例实操
java
荣码2 天前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python