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

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

相关推荐
用户8307196840822 分钟前
Java IO三大模型(BIO/NIO/AIO)超详细总结
java
sheji34162 分钟前
【开题答辩全过程】以 基于SSM的花店销售管理系统为例,包含答辩的问题和答案
java
Mr_sun.14 分钟前
Day09——入退管理-入住-2
android·java·开发语言
MAGICIAN...25 分钟前
【java-软件设计原则】
java·开发语言
JH307331 分钟前
为什么switch不支持long
java
盐真卿1 小时前
python第八部分:高级特性(二)
java·开发语言
上海合宙LuatOS1 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程
汤姆yu1 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
TT哇1 小时前
【实习】银行经理端线下领取扫码功能实现方案
java
野犬寒鸦1 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习