java - Apache POI 找不到突出显示的文本
问题描述
我有一个以 doc 格式保存的文件,我需要提取突出显示的文本。我有如下代码:
HWPFDocument document = new HWPFDocument(fis);
Range r = document.getRange();
for (int i=0;i<5;i++) {
CharacterRun t = r.getCharacterRun(i);
System.out.println(t.isHighlighted());
System.out.println(t.getHighlightedColor());
System.out.println(r.getCharacterRun(i).SPRM_HIGHLIGHT);
System.out.println(r.getCharacterRun(i));
}
以上方法都没有显示文本被突出显示,但是当我打开它时,它被突出显示。可能是什么原因,以及如何查找文本是否突出显示?
解决方案
Word
使用两种不同的方法可以突出显示文本。首先是将突出显示应用于文本运行。其次是对单词或段落应用底纹。
对于第一个和 using *.doc
,Word
二进制文件格式apache poi
提供CharacterRun中的方法。第二个apache poi
提供Paragraph.getShading。但这仅在阴影适用于整个段落时才设置。如果阴影仅应用于单次运行,则不apache poi
提供任何内容。所以需要使用底层 SprmOperation
的 s 。
Microsoft 的文档 2.6.1 Character Properties描述了sprmCShd80 (0x4866)
哪个是“指定文本背景阴影的 Shd80 结构”。所以我们需要寻找它。
例子:
import java.io.FileInputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.*;
import org.apache.poi.hwpf.sprm.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class HWPFInspectBgColor {
private static void showCharacterRunInternals(CharacterRun run) throws Exception {
Field _chpx = CharacterRun.class.getDeclaredField("_chpx");
_chpx.setAccessible(true);
SprmBuffer sprmBuffer = (SprmBuffer) _chpx.get(run);
for (SprmIterator sprmIterator = sprmBuffer.iterator(); sprmIterator.hasNext(); ) {
SprmOperation sprmOperation = sprmIterator.next();
System.out.println(sprmOperation);
}
}
static SprmOperation getCharacterRunShading(CharacterRun run) throws Exception {
SprmOperation shd80Operation = null;
Field _chpx = CharacterRun.class.getDeclaredField("_chpx");
_chpx.setAccessible(true);
Field _value = SprmOperation.class.getDeclaredField("_value");
_value.setAccessible(true);
SprmBuffer sprmBuffer = (SprmBuffer) _chpx.get(run);
for (SprmIterator sprmIterator = sprmBuffer.iterator(); sprmIterator.hasNext(); ) {
SprmOperation sprmOperation = sprmIterator.next();
short sprmValue = (short)_value.get(sprmOperation);
if (sprmValue == (short)0x4866) { // we have a Shd80 structure, see https://msdn.microsoft.com/en-us/library/dd947480(v=office.12).aspx
shd80Operation = sprmOperation;
}
}
return shd80Operation;
}
public static void main(String[] args) throws Exception {
HWPFDocument document = new HWPFDocument(new FileInputStream("sample.doc"));
Range range = document.getRange();
for (int p = 0; p < range.numParagraphs(); p++) {
Paragraph paragraph = range.getParagraph(p);
System.out.println(paragraph);
if (!paragraph.getShading().isEmpty()) {
System.out.println("Paragraph's shading: " + paragraph.getShading());
}
for (int r = 0; r < paragraph.numCharacterRuns(); r++) {
CharacterRun run = paragraph.getCharacterRun(r);
System.out.println(run);
if (run.isHighlighted()) {
System.out.println("Run's highlighted color: " + run.getHighlightedColor());
}
if (getCharacterRunShading(run) != null) {
System.out.println("Run's Shd80 structure: " + getCharacterRunShading(run));
}
}
}
}
}
推荐阅读
- jquery - jQuery.trim() 不工作
- javascript - 是否可以将人类用户和机器人(蜘蛛、爬虫)分开并仅在 AMP 页面上为人类用户显示广告横幅?
- shopify - 首次亮相 shopify 主题:在收藏页面上更改图像大小
- xamarin - Xamarin Forms - 将构造函数添加到 MasterDetailPage.Master
- shopify - Shopify cart.js(铆钉版本)一次删除多个产品而不是一个
- java - Android GraphView 和 Mediaplayer 不同步
- google-app-engine - Google App Engine 高成本
- ruby-on-rails - 当我尝试在 Rails 5 中添加占位符关联记录时,嵌套字段表单出现错误
- android - 在自己的应用程序中显示网站是否合法?
- angular - Angular 6 - run method in service every 10 seconds