Создание списка маркеров в текстовом документе с использованием Java с API Apache POI

Мне нужен список маркеров в текстовом документе с отступом и настраиваемыми маркерами, который создается через Java с помощью API Apache POI. Я искал и не могу найти документ Word. Он доступен для слайдов Powerpoint с использованием текстового поля. Но я не хочу использовать текстовое поле. Пожалуйста, дайте мне знать о возможностях этого достичь. Любая помощь очень ценится. Спасибо! С уважением, Арун Ганеш. п


person ioshunter    schedule 18.01.2012    source источник


Ответы (2)


На самом деле это возможно только с форматом OOXML 2007 года и выше (с использованием XWPF POI). Поскольку он основан на XML, вы всегда можете выполнять манипуляции с DOM для достижения желаемого. Самый простой способ обозначить маркированный список - создать маркированный список и добавить закладку в качестве текста этого маркера. При обработке документа найдите свою закладку, затем получите узел DOM с помощью

`org.w3c.dom.Node bkmk = bookmark.getctBookmark).getDomNode();`

Затем скопируйте родительский узел bkmk, который является тегом абзаца. Теперь у вас есть дублированный тег абзаца, в котором есть все необходимые дочерние теги, которые должны быть частью маркированного списка. Видите ли, в OOXML нет структуры маркированного списка, это просто последовательное продолжение абзацев с подобными субтегами нумерации.

<w:p>
  <w:pPr>
    <w:pStyle w:val="style0" />
    <w:numPr>
      <w:ilvl w:val="1" />
      <w:numId w:val="2" />
    </w:numPr>
    <w:tabs>
      <w:tab w:leader="none" w:pos="1807" w:val="left" />
    </w:tabs>
    <w:spacing w:after="0" w:before="120" />
    <w:ind w:end="907" w:hanging="360" w:start="907" />
    <w:jc w:val="both" />
  </w:pPr>
  <w:bookmarkStart w:id="1" w:name="GIVES" />
  <w:r>
    <w:t>To be inserted Next Bullet</w:t>
  </w:r>
  <w:bookmarkEnd w:id="1" />
  <w:r>
    <w:rPr>
      <w:rFonts w:eastAsia="Times New Roman" />
      <w:color w:val="000000" />
      <w:lang w:eastAsia="en-US" />
    </w:rPr>
  </w:r>
</w:p>

Ключевые теги - это и, и я не очень хорошо разбираюсь в XML-значениях тегов, но если вы разархивируете любой docx и посмотрите на document.xml (конечно, после его форматирования с помощью tidy), вы можете увидеть различия между абзацами с нумерацией и без.

Итак, когда у вас есть клон вашего тега, вы можете пройти по узлу с помощью DOM, чтобы получить и заменить значение узла на то, что вы хотите, или вы можете использовать xpath для поиска узла (w: r / w: t). Вы должны настроить NamespaceContext и дать ему правильный код, чтобы понять префикс w:

        NodeList nl;
        XPath xp = XPathFactory.newInstance().newXPath();
        NamespaceContext nsContext = new NamespaceContext(){
            @Override public String getNamespaceURI(String prefix) {
                if (prefix.equals("w")) {
                    return "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
                }
                return null;
              }

              @Override public String getPrefix(String namespaceURI) {
                return null;
              }

              @Override public Iterator<?> getPrefixes(String namespaceURI) {
                return Collections.emptyList()
                    .iterator();
              }
            };
        xp.setNamespaceContext(nsContext);
        nl =  (NodeList) xp.evaluate("w:r/w:t", copy, XPathConstants.NODESET);

Теперь пройдемся по nodeList, setNodeValue ("Hello World"). Вы можете сделать это после клонирования и выполнения: paragraph.getParentNode().insertBefore(bkmk, paragraph);

чтобы получить столько пунктов, сколько хотите. Если ты это сделаешь

 `paragraph.getParentNode().append(bkmk)`

ваш новый маркер будет в самом конце документа!

Итак, вы должны выполнить insertBefore (это единственная доступная манипуляция с dom-узлом, кроме добавления). Это оставляет вас с исходным пустым маркером в конце с закладкой в ​​нем. Вам нужно удалить закладку с помощью paragraph.getParentNode (). RemoveChild (paragraph);

Затем сохраните файл с помощью POI.

По сути, POI не поддерживает маркированные списки, потому что OOXML на самом деле не поддерживает маркированные списки. Маркированные списки - это просто набор абзацев с тегами нумерации в качестве дочерних. Но с POI вы всегда можете перейти к основным манипуляциям с DOM, и вы можете проверить DOM с помощью unzip and tidy.

person chugadie    schedule 04.02.2013

HWPF от POI - это незрелый api - ведущему разработчику была предложена работа, которая заключалась в подписании соглашения о неразглашении, и он был вынужден отказаться от работы с ним - и может оказаться невозможным использовать его для создания файлов, которые вы хотите.

См. продолжение сообщения

person Õzbek    schedule 18.01.2012