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

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

相关推荐
代码栈上的思考10 小时前
深入解析Spring IoC核心与关键注解
java·后端·spring
Mai Dang10 小时前
SpringBoot4用Swagger
java
geekmice11 小时前
实现一个功能:springboot项目启动将controller地址拼接打印到txt文件
java·spring boot·后端
老华带你飞11 小时前
旅游|基于Java旅游信息系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·旅游
小石头 1008611 小时前
【JavaEE】进程和线程的区别
java·java-ee
oioihoii12 小时前
C++对象生命周期与析构顺序深度解析
java·开发语言·c++
BBB努力学习程序设计12 小时前
Java枚举(Enum):定义固定值的"类型安全"利器
java
It's now12 小时前
BeanRegistrar 的企业级应用场景及最佳实践
java·开发语言·spring
毕设源码-赖学姐12 小时前
【开题答辩全过程】以 基于Java的小区物业管理系统APP的设计与实现为例,包含答辩的问题和答案
java·开发语言