无法从 Word (Apache POI) 读取双向字符串

Posted

技术标签:

【中文标题】无法从 Word (Apache POI) 读取双向字符串【英文标题】:bidi string can't be read from Word (Apache POI) 【发布时间】:2021-09-26 06:11:06 【问题描述】:

在用序列包装后,我正在使用 Apache POI 将双向字符串写入 MS Word 文件 aString = "\u202E" + aString + "\u202C"; 文本在文件中正确呈现,当我再次检索字符串时读取正常。但是,如果我以任何方式修改文件,突然间,读取该字符串会使用 isBlank() 返回 true。 提前感谢您的任何建议/帮助!

【问题讨论】:

您从Word 阅读的内容到底如何?您确定您阅读了正确的文本吗?有时Word 会出于非常奇怪的原因在文本运行中拆分文本。有时也会出现空文本运行。如果启用了拼写检查并且文本是Word 没有为拼写检查设置的语言,那么有时每个包含字母的空格都将在单独的文本运行中。如果您随后得到一个仅包含空格的文本运行,则 String.isBlank() 将为真。 @AxelRichter,哦,嗨!是你指导我解决编码问题。我确实想到了多次运行(和段落)的可能性。但是调用 getRuns().size() 会返回 1。奇怪的是,只要我不手动修改 MS Word 文件,字符串的读取效果就非常好。一个字母和程序写的所有文本都变为空。它存在并且从文件中可见,但程序无法再读取它! 【参考方案1】:

Microsoft WordOffice Open XML *.docx 格式存储双向文本时,它有时会使用特殊的文本运行元素w:bdo (bi d方向性方向)。 Apache poi 直到现在才读取这些元素。所以如果XWPFParagraph 包含这样的元素,那么paragraph.getText() 将返回一个空字符串。

可以使用org.apache.xmlbeans.XmlCursor 真正从所有XWPFParagraphs 中获取所有文本,如下所示:

import java.io.FileInputStream;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.xmlbeans.XmlCursor;

public class ReadWordParagraphs 
    
 static String getAllTextFromParagraph(XWPFParagraph paragraph) 
  XmlCursor cursor =  paragraph.getCTP().newCursor();
  return cursor.getTextValue();
 

 public static void main(String[] args) throws Exception 

  XWPFDocument document = new XWPFDocument(new FileInputStream("WordDocument.docx"));
  
  for (XWPFParagraph paragraph : document.getParagraphs()) 
   System.out.println(paragraph.getText()); // will not return text in w:bdo elements
   System.out.println(getAllTextFromParagraph(paragraph)); // will return all text content of paragraph
  
 

【讨论】:

完美解决方案!谢谢!我应该使用 XmlCursor 来读取字符串并完全停止使用 paragraph.getText() 吗?

以上是关于无法从 Word (Apache POI) 读取双向字符串的主要内容,如果未能解决你的问题,请参考以下文章

Java Apache POI 读取 Word (.doc) 文件并获取使用的命名字符样式

读取word文档,暂时不能读取图片,案例代码

用 Apache POI 读取 XLSX 数据

java 读取word

无法从Excel读取'java.lang.ClassCastException:org.apache.poi.hssf.usermodel.HSSFCell无法强制转换为java.lang.S

java读取word内容