пои XWPF двойной пробел

Я использую библиотеку apache POI.XWPF для создания текстовых документов. Последние пару дней я искал, как сделать двойные пробелы для всего документа. Я проверил javadocs Apache и просто поискал в Интернете, но, похоже, не нашел ответов.

Я нашел метод addBreak(), но он не будет работать, потому что пользователь будет вводить несколько абзацев, и разбивать эти абзацы на отдельные строки кажется неразумным. Если этот метод используется для каждого абзаца, то он не будет создавать двойной пробел между каждой строкой, а между каждым абзацем.

Вот небольшая часть кода, который у меня сейчас есть.

public class Paper {
        public static void main(String[] args) throws IOException, XmlException {
ArrayList<String> para = new ArrayList<String>();
        para.add("The first paragraph of a typical business letter is used to state the main point of the letter. Begin with a friendly opening; then quickly transition into the purpose of your letter. Use a couple of sentences to explain the purpose, but do not go in to detail until the next paragraph.");
        para.add("Beginning with the second paragraph, state the supporting details to justify your purpose. These may take the form of background information, statistics or first-hand accounts. A few short paragraphs within the body of the letter should be enough to support your reasoning.");

        XWPFDocument document = new XWPFDocument();

        //Calls on createParagraph() method which creates a single paragraph
        for(int i=0; i< para.size(); i++){
            createParagraph(document, para.get(i));
        }

        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream("ResearchPaper.docx");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        try {
            document.write(outStream);
            outStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


}

//Creates a single paragraph with a one tab indentation
    private static void createParagraph(XWPFDocument document, String para) {
        XWPFParagraph paraOne = document.createParagraph();
        paraOne.setFirstLineIndent(700); // Indents first line of paragraph to the equivalence of one tab
        XWPFRun one = paraOne.createRun();
        one.setFontSize(12);
        one.setFontFamily("Times New Roman");
        one.setText(para);
    }



}

Просто чтобы убедиться, что мой вопрос ясен, я пытаюсь выяснить, как удвоить пробел в текстовом документе (.docx). Таким образом, между каждой строкой должен быть один пробел. Это то же самое, что и нажатие ctrl+2 при редактировании документа Word.

Спасибо за любую помощь.


person develop1    schedule 29.06.2015    source источник


Ответы (1)


Похоже, что для того, чего вы пытаетесь достичь, не существует метода высокого уровня. В этом случае вам нужно углубиться в низкоуровневый API Apache POI. Ниже приведен способ сделать это. Я не говорю, что это лучший способ сделать это, я обнаружил, что он работает только для меня, когда я хочу воссоздать какую-то странную функцию MS Word.

1. Узнайте, где хранится информация в документе

Если вам нужно что-то подправить вручную, создайте 2 документа с как можно меньшим содержанием: один содержит то, что вы хотите сделать, а другой — нет. Сохраняйте оба как документы Office XML, потому что это облегчает чтение. Сравните эти файлы - должно быть только несколько изменений, и вы должны указать свое местоположение в структуре документа.

Для вашего случая это то, что вы ищете.

Неизмененный документ:

<w:body><w:p> <!-- only included here so you know where to look -->
<w:pPr>
    <w:jc w:val="both" />
    <w:rPr>
        <w:lang w:val="nl-BE" />
    </w:rPr>
</w:pPr>

Измененный документ:

<w:body><w:p>
<w:pPr>
    <w:spacing w:line="480" w:lineRule="auto" /> <!-- BINGO -->         
    <w:jc w:val="both" />
    <w:rPr>
        <w:lang w:val="nl-BE" />
    </w:rPr>
</w:pPr>

Итак, теперь вы знаете, что вам нужен объект с именем spacing, что у него есть некоторые свойства и что он хранится где-то в объекте Paragraph.

2. Доберитесь до этого места через низкоуровневый API, если это вообще возможно.

Эта часть сложна, потому что имена узлов XML несколько загадочны и, возможно, вы не очень хорошо знаете терминологию. Кроме того, API не всегда представляет собой сопоставление имен узлов 1:1, поэтому вам нужно сделать несколько предположений и просто попытаться выполнить вызовы методов. Совет для профессионалов: загрузите исходный код Apache POI !! Вы зайдете в тупик и, возможно, не доберетесь туда, куда хотите, по кратчайшему пути, но когда вы это сделаете, вы почувствуете себя таинственным мастером POI. А потом вы пишете об этом злорадные посты на сайтах вопросов и ответов.

Для вашего случая в MS Word это путь, который вы можете выбрать (не обязательно лучший, я не эксперт по высокоуровневому API):

// you probably don't need this first line
// but you'd need it if you were manipulating an existing document
IBody body = doc.getBodyElements().get(0).getBody();
for (XWPFParagraph par : body.getParagraphs()) {
    // work the crazy abbreviated API magic
    CTSpacing spacing = par.getCTP().getPPr().getSpacing();
    if (spacing == null) {
        // it looks hellish to create a CTSpacing object yourself
        // so let POI do it by setting any Spacing parameter
        par.setSpacingLineRule(LineSpacingRule.AUTO);
        // now the Paragraph's spacing shouldn't be null anymore
        spacing = par.getCTP().getPPr().getSpacing();
    }
    // you can set your value, as demonstrated by the XML
    spacing.setAfter(BigInteger.valueOf(480));
    // not sure if this one is necessary
    spacing.setLineRule(STLineSpacingRule.Enum.forString("auto"));
}

3. Наслаждайтесь своей славой!

person blagae    schedule 29.06.2015