用 java 批量处理 word 文档时,给指定文字上色是个挺常见的需求——标红合同里改动的条款、给审核意见加个颜色区分、或者让批量生成的报告更容易一眼看出重点。这个需求看着简单,但实际做的时候会发现"改一段"和"改一个词"用的方法不一样,选错了方法经常出现"改了但没完全生效"的情况。这篇整理一下三种常见做法。
环境准备
代码用的是 spire.doc for java 这个库,maven 依赖配置如下:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupid>e-iceblue</groupid>
<artifactid>spire.doc</artifactid>
<version>13.5.3</version>
</dependency>
</dependencies>不用 maven 的话官网也能直接下 jar 手动导入。免费版会在生成的文件里加提示文字,正式环境记得提前换成授权版本。
一、用段落样式整段上色
如果要把一整个段落的文字都改成同一种颜色,最直接的做法是新建一个 paragraphstyle,把颜色设置在样式里,再把样式应用到段落上。
import com.spire.doc.document;
import com.spire.doc.fileformat;
import com.spire.doc.section;
import com.spire.doc.documents.paragraph;
import com.spire.doc.documents.paragraphstyle;
import java.awt.*;
public class colorwholeparagraph {
public static void main(string[] args) {
document document = new document();
document.loadfromfile("report.docx");
section section = document.getsections().get(0);
paragraph paragraph = section.getparagraphs().get(0);
paragraphstyle style = new paragraphstyle(document);
style.setname("highlightred");
style.getcharacterformat().settextcolor(new color(178, 34, 34));
document.getstyles().add(style);
paragraph.applystyle(style.getname());
document.savetofile("output/colored.docx", fileformat.docx);
}
}
这个方法适合段落本身格式比较"干净"、没有被手动调过格式的场景。这里有个注意事项:给段落应用样式,并不会覆盖段落里已经存在的、直接设置在文字上的格式。 word 的格式优先级是"直接格式高于样式格式",如果段落里有些文字之前已经单独设过颜色(比如被人手动改过,或者是从别处粘贴过来的时候带了自己的格式),那应用新样式之后,这部分文字的颜色是不会变的,最终效果就是整段颜色改了一半。想保证段落里的每个字都变色,得用下面第二种方法。
二、直接遍历文字块上色
一个段落的内容其实是由一串子对象组成的,真正的文字存放在 textrange 对象里,中间可能还穿插着换行符、图片这些其他类型的子对象。遍历这些子对象,找到 textrange 类型的逐个设置颜色,就绕开了上面样式优先级的问题,因为这是直接改的是文字本身的格式。
import com.spire.doc.document;
import com.spire.doc.section;
import com.spire.doc.documents.paragraph;
import com.spire.doc.fields.textrange;
import com.spire.doc.fileformat;
import java.awt.*;
public class colorparagraphruns {
public static void main(string[] args) {
document document = new document();
document.loadfromfile("report.docx");
section section = document.getsections().get(0);
paragraph paragraph = section.getparagraphs().get(1);
for (int i = 0; i < paragraph.getchildobjects().getcount(); i++) {
if (paragraph.getchildobjects().get(i) instanceof textrange) {
textrange run = (textrange) paragraph.getchildobjects().get(i);
run.getcharacterformat().settextcolor(color.blue);
}
}
document.savetofile("output/coloredruns.docx", fileformat.docx);
}
}
代码比第一种方法啰嗦一点,但实测更稳,尤其是处理那些已经被人工编辑过、格式不太干净的文档时,基本上都得用这种方式才能保证颜色真的全改到位。
三、查找指定文字并上色
有时候要改颜色的不是某一整段,而是散落在文档各处的某个词或短语。用 findallstring() 找出所有匹配项,每个匹配结果都是一个 textselection,可以转成可格式化的文字范围。
import com.spire.doc.document;
import com.spire.doc.fileformat;
import com.spire.doc.documents.textselection;
import com.spire.doc.fields.textrange;
import java.awt.*;
public class colormatchedtext {
public static void main(string[] args) {
document document = new document();
document.loadfromfile("report.docx");
textselection[] matches = document.findallstring("机密", false, true);
for (textselection match : matches) {
textrange range = match.getasonerange();
range.getcharacterformat().settextcolor(color.red);
}
document.savetofile("output/coloredmatches.docx", fileformat.docx);
}
}
这里 getasonerange() 这一步不能省。文档里看上去是一个完整的词或句子,内部存储时不一定是单个 textrange——拼写检查状态、修订痕迹、或者原文档编辑时留下的格式碎片,都可能导致同一个匹配结果被拆成好几个相邻的文字块。getasonerange() 会把命中的这几个块合并成一个整体再返回,这样格式化的时候才是整个匹配结果一起变色,不然很容易出现只改了匹配词前半截颜色的情况。
补充
颜色用的就是普通的 java.awt.color,color.red 这种命名常量,或者 new color(r, g, b) 自己传 rgb 值都可以。另外 findallstring() 后面跟着两个布尔参数,分别控制大小写敏感和全词匹配,实际用之前最好核对一下这两个参数跟自己的搜索词搭不搭——比如开了全词匹配去搜"pdf",是匹配不到"pdfs"或者"pdf-2"这种词里带着"pdf"的情况的。
三种方法怎么选:如果能确认文档格式没被手动改过,样式着色写起来最快;如果文档来源不可控(比如是用户上传的、之前被编辑过的),直接遍历文字块上色更保险;要按关键词批量改颜色,就用查找+上色这套组合。选错了方法,最常见的表现就是"运行没报错,但颜色只改了一半",排查起来还挺费劲的,提前想清楚场景能省不少事。
到此这篇关于java修改word文档字体颜色的三种实现方法的文章就介绍到这了,更多相关java修改word字体颜色内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论