【问题标题】:problems with symbols (apostrophe, parenthesis) when writing RTL language with Apache POI XWPFDocument使用 Apache POI XWPFDocument 编写 RTL 语言时出现符号(撇号、括号)的问题
【发布时间】:2023-03-20 06:15:01
【问题描述】:

我一直在尝试将希伯来语数据从 excel 文件复制到文档中。 虽然字母本身被正确复制,但只要涉及到一些符号,就会变得一团糟。

例如:我得到的是 )text(

而不是 (text)

这是我目前的代码:

XWPFParagraph newPara = document.insertNewParagraph(cursor);
newPara.setAlignment (ParagraphAlignment.RIGHT); 
CTP ctp = newPara.getCTP();
CTPPr ctppr;
if ((ctppr = ctp.getPPr()) == null) ctppr = ctp.addNewPPr();
ctppr.addNewBidi().setVal(STOnOff.ON);
XWPFRun newParaRun = newPara.createRun();
newParaRun.setText(name);

我尝试了一些“双向文本方向支持”(bidi) 行

(从这里得到它: how change text direction(not paragraph alignment) in document in apache poi word?(XWPF))

但不是这样,也与对齐无关......

【问题讨论】:

  • 无法重现您的问题。当我在链接答案中使用run.setText("(שָׁלוֹם)"); 而不是run.setText("السلام عليكم"); 时,它可以正常工作。您能否展示一个完整的示例来重现您的问题?
  • 这很奇怪。我现在用你的代码和你的例子试了一下,得到了 )שלום( 事情是,在 System.out.println("(שלום)") 它完美地出现了。问题出在文档的某个地方.我已经开始用String.replace手动处理了,但显然还很不理想...
  • 抱歉,那就帮不上忙了。对我来说,它可以使用我的示例代码和run.setText("(שָׁלוֹם)");。使用 apache poi4.1.2。它创建一个 RTL 段落,其中包含一个带有文本 (שָׁלוֹם) 的运行。尝试使用Windows 10MS Word 以及使用Ubuntu LinuxLibreoffice Calc 打开结果WordDocument.docx。两者都运作良好。
  • 没关系,谢谢 :)
  • 您是否使用WordPad 打开*.docx 文件?这对我来说是)שָׁלוֹם(。但这只是说明WordPad 的一个缺点,它不能正确显示双向文本。

标签: java apache-poi


【解决方案1】:

使用较旧的文字处理软件应用程序时,当 LTR 字符和 RTL 字符在一个文本运行中混合时似乎会出现问题。然后使用特殊的双向字符类型可能是解决方案。见https://en.wikipedia.org/wiki/Bidirectional_text#Table_of_possible_BiDi_character_types

另见bidirectional with word document using Aphace POI

使用以下作品:

import java.io.FileOutputStream;

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

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;

public class CreateWordRTLParagraph {

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

  XWPFDocument doc= new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("Paragraph 1 LTR");

  paragraph = doc.createParagraph();

  CTP ctp = paragraph.getCTP();
  CTPPr ctppr;
  if ((ctppr = ctp.getPPr()) == null) ctppr = ctp.addNewPPr();
  ctppr.addNewBidi().setVal(STOnOff.ON);

  run = paragraph.createRun();
  String line = "(שָׁלוֹם)";
  run.setText("\u202E" + line + "\u202C");

  paragraph = doc.createParagraph();
  run = paragraph.createRun();
  run.setText("Paragraph 3 LTR");
    
  FileOutputStream out = new FileOutputStream("WordDocument.docx");
  doc.write(out);
  out.close();
  doc.close();    
 }
}

它在包含 LTR 字符(())和 RTL 字符(שָׁלוֹם)的文本行之前使用 U+202E RIGHT-TO-LEFT OVERRIDE (RLO),在该文本行之后使用 U+202C POP DIRECTIONAL FORMATTING (PDF)。这告诉文字处理软件 RTL 在哪里开始和结束。这会导致使用MS Word 365WordPad 为我提供正确的输出。


apache poi 5.0.0 用于Bidi .setVal(STOnOff.ON) 不太可能,但可以使用.setVal(true)

  //ctppr.addNewBidi().setVal(STOnOff.ON); // up to apache poi 4.1.2
  ctppr.addNewBidi().setVal(true); // from apache poi 5.0.0 on

【讨论】:

  • 非常感谢您的努力!仍然是 )שלום( 对我来说...
  • 我会尝试下载其中一个软件,看看那里是否可以正常工作...非常感谢 :)
  • 它可以在写字板中正常工作。问题是它没有显示一些签名,但我想这是另一个问题。非常感谢!
  • 所以由于某种原因它在 microsoft word 上不起作用:/ 我尝试了很多东西。当我在一些(不是全部,而是一些)其他文字处理器上打开它时它工作正常,但它们有不同的问题。还有其他解决方法/方向吗?
  • @librogil:那么您是否尝试过标记每个 LTR 和 RTL 块?例如:run.setText("\u200E" + "(" + "\u200F" + "שָׁלוֹם" + "\u200E" + ")");?
猜你喜欢
  • 2015-09-27
  • 1970-01-01
  • 2014-01-28
  • 2014-03-11
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 2011-05-25
  • 2023-03-27
相关资源
最近更新 更多