Создание списка маркеров в текстовом документе с использованием Java с API Apache POI - PullRequest
6 голосов
/ 18 января 2012

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

Ответы [ 2 ]

2 голосов
/ 04 февраля 2013

Это действительно возможно только в формате 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, кроме append),Это оставляет вас с оригинальной пустой точкой маркера в конце, с закладкой в ​​нем.Вам необходимо удалить закладку с помощью para.getParentNode (). RemoveChild (абзац);

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

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

1 голос
/ 18 января 2012

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

См. продолжение поста

...