двунаправленный текстовый документ с использованием Aphace POI - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь добавить текст на иврите в текстовый документ, и он работает нормально, но когда я добавляю знаки препинания, он становится грязным.

Это код, который я запускаю:

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

    XWPFDocument document = new XWPFDocument();
    XWPFParagraph paragraph = document.createParagraph();

    paragraph.setAlignment(ParagraphAlignment.LEFT);

    // make RTL direction
    CTP ctp = paragraph.getCTP();
    CTPPr ctppr;
    if ((ctppr = ctp.getPPr()) == null) {
        ctppr = ctp.addNewPPr();
    }
    ctppr.addNewBidi().setVal(STOnOff.ON);

    XWPFRun run = paragraph.createRun();
    run.setText("שלום עולם !");

    // create the document in the specific path by giving it a name
    File newFile = new File("helloWorld.docx");

    // insert document to newFile
    try {
        FileOutputStream output = new FileOutputStream(newFile);
        document.write(output);
        output.close();
        document.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Это «helloWorld.docx», который я получаю:

снимок экрана

И вот как это должно быть:

снимок экрана

Более того, я хочу, чтобы весь документ был RTL (даже с двунаправленным), а не только конкретный c абзац.

Спасибо за помощь!

1 Ответ

1 голос
/ 12 апреля 2020

Это хорошо известная проблема с использованием двунаправленного текста. Восклицательный знак, а также пробел не являются символами справа налево. Поэтому мы должны пометить их как таковые, если это необходимо. RIGHT-TO-LEFT MARK (RLM) - это U+200F. См. https://en.wikipedia.org/wiki/Bidirectional_text#Table_of_possible_BiDi_character_types.

У меня работает следующий код:

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();
  CTP ctp = paragraph.getCTP();
  CTPPr ctppr;
  if ((ctppr = ctp.getPPr()) == null) ctppr = ctp.addNewPPr();
  ctppr.addNewBidi().setVal(STOnOff.ON);

  XWPFRun run = paragraph.createRun();
  run.setText("שלום עולם \u200F!\u200F");

  FileOutputStream out = new FileOutputStream("WordDocument.docx");
  doc.write(out);
  out.close();
  doc.close();

 }
}

Обратите внимание на \u200F знак после пробел и восклицательный знак.

Если текстовые строки исходят из файла, маркировка отдельных символов не будет лучшей практикой. Затем вся текстовая строка должна быть помечена как текст справа налево. Для этого мы можем встроить текстовые строки в U+202B RIGHT-TO-LEFT EMBEDDING (RLE), за которым следует U+202C POP DIRECTIONAL FORMATTING (PDF).

Пример:

import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

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;

import java.util.List;

public class CreateWordRTLParagraphsFromFile {

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

  List<String> lines = Files.readAllLines(new File("HebrewTextFile.txt").toPath(), StandardCharsets.UTF_8);

  XWPFDocument doc= new XWPFDocument();

  for (String line : lines) {

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

   XWPFRun run = paragraph.createRun();
   run.setText("\u202E" + line + "\u202C");

  }

  FileOutputStream out = new FileOutputStream("WordDocument.docx");
  doc.write(out);
  out.close();
  doc.close();

 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...