Как исправить ширину столбцов в таблице, которая находится в ячейке другой таблицы с помощью apache poi и Java?

Я разбираю XML, в котором есть HTML-теги. После анализа XML я пытаюсь создать таблицу, которая находится в ячейке другой таблицы, и создать текстовый документ с этим содержимым. Я реализовал таблицу внутри таблицы с помощью ответа на этот Вопрос . Однако я не могу установить ширину столбцов вложенной таблицы. Когда создается текстовый документ, сгенерированная вложенная таблица настолько уродлива с очень узкими столбцами, что ее необходимо вручную настроить, чтобы иметь желаемую ширину столбца. Я хотел бы установить некоторые значения по умолчанию в качестве желаемой ширины столбца. Сгенерированный текстовый документ с вложенной таблицей представлен на рисунке. Я использую следующий код для установки ширины столбца, но пока не повезло.

  for (int i = 0; i < nestedtable.getNumberOfRows(); i++) {
  XWPFTableRow row = nestedtable.getRow(i);
  int numCells = row.getTableCells().size();
  for (int j = 0; j < numCells; j++) {
    XWPFTableCell cell = row.getCell(j);
    CTTblWidth cellWidth = cell.getCTTc().addNewTcPr().addNewTcW();
    CTTcPr pr = cell.getCTTc().addNewTcPr();
    pr.addNewNoWrap();
    cellWidth.setW(BigInteger.valueOf(400));
  }
}

Как мне выйти из этой проблемы? Сгенерированный текстовый документ выглядит так уродливо из-за этой структуры вложенных таблиц.

Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вопрос, который вы связали, был о том, как вставить таблицу в ячейку таблицы в таблице Word с помощью Apache POI. Ничего о том, как установить ширину столбцов. И, поскольку он выпущен в 2017 году, он отвечает на это, используя версии Apache POI 2017 года. Но Apache POI находится в стадии разработки. Таким образом, текущие версии будут иметь более простые методы для работы.

Специально для установки ширины XWPFTable и/или XWPFTableCell текущая версия Apache POI 5.2.3 предоставляет методы setWidth в XWPFTable , а также в XWPFTableCell. Самый простой public void setWidth(java.lang.String widthValue). Здесь String widthValue может быть шириной до значения «авто», целым числом (20-е точки) или процентом («nn.nn%»).

Кроме того, установка границ теперь намного проще, так как теперь есть XWPFTable.set*Border методы.

Таким образом, теперь код должен выглядеть так, используя текущий POI Apache.

import java.io.*;

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

public class CreateWordTableInTable {
    
 static void setAllBorders(XWPFTable table, XWPFTable.XWPFBorderType borderType, int size, int space, java.lang.String rgbColor) {
   table.setTopBorder(borderType, size, space, rgbColor);
   table.setRightBorder(borderType, size, space, rgbColor);
   table.setBottomBorder(borderType, size, space, rgbColor);
   table.setLeftBorder(borderType, size, space, rgbColor);
   table.setInsideHBorder(borderType, size, space, rgbColor);
   table.setInsideVBorder(borderType, size, space, rgbColor);    
 }

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

    XWPFDocument document = new XWPFDocument();

    XWPFTable tableOne = document.createTable(2,2);
    
    tableOne.setWidth("100%");
    
    XWPFTableRow tablerow = tableOne.getRow(0);
    
    tablerow.getCell(0).setWidth("40%");
    tablerow.getCell(1).setWidth("60%");
    
    tablerow.getCell(0).setText("Test");
    tablerow.getCell(1).setText("Test");

    tablerow = tableOne.getRow(1);
    tablerow.getCell(0).setText("Test");

    XWPFParagraph paragraph = tablerow.getCell(1).getParagraphArray(0);
    XWPFTable tableTwo = tablerow.getCell(1).insertNewTbl(paragraph.getCTP().newCursor());

    tableTwo.setWidth(0); // This is necessary because a XWPFTable created by insertNewTbl seems not to have full internally structure. It lacks the cell width field in this case.
    tableTwo.setWidth("100%");
    
    setAllBorders(tableTwo, XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
    
    tablerow = tableTwo.createRow();
    tablerow.createCell().setText("aaaaaaaaaa");
    tablerow.createCell().setText("jjjjjjjj"); 
    tablerow = tableTwo.createRow(); 
    tablerow.getCell(0).setText("bbbbbbbbbb"); 
    tablerow.getCell(1).setText("gggggggggg");

    try (FileOutputStream out = new FileOutputStream("./CreateWordTableInTable.docx")) {
     document.write(out);
    }
    document.close();

 }
}

Примечание: XWPFTable, созданный insertNewTbl, похоже, не имеет полной внутренней структуры. Например, у него нет настройки границы по умолчанию, и ему не хватает поля внутренней ширины ячейки. Вот почему необходима явная установка границ. И вызов setWidth(int width) необходим перед вызовом setWidth(java.lang.String widthValue), поскольку первый устанавливает внутреннее поле ширины ячейки, а второй полагается на наличие этого поля и терпит неудачу, если его нет.

Результат выглядит так для меня:

Большое спасибо за помощь! Иногда я получаю индекс "IndexOutOfBoundsException": 6, размер: 1..... в строке -- XWPFTable tableTwo = tablerow.getCell(0).insertNewTbl(paragraph.getCTP().newCurso‌​r()); Объект абзаца здесь действителен. Индекс равен 6, что также хорошо, так как я хочу создать таблицу в 6-м абзаце. ---- Параграф XWPFParagraphnestedtable = tableRowThree.getCell(0).getParagraphArray(6);... все еще почему отображается это исключение? Должен ли абзац всегда быть 0, чтобы вставить вложенную таблицу? могут ли быть другие абзацы перед абзацем вложенной таблицы?

Jeet 15.02.2023 14:26

@Jeet: мой код завершен, протестирован и работает без исключений. Значит, вы используете код, отличный от моего. Это не то, что можно обсуждать в комментариях. Пожалуйста, задайте вопрос об этой проблеме и предоставьте полный код, необходимый для воспроизведения этой проблемы.

Axel Richter 15.02.2023 14:34

@Jeet: «Должен ли абзац всегда быть равен 0, чтобы вставить вложенную таблицу?» Нет. Это должен быть существующий абзац. Кстати: tableRowThree.getCell(0).getParagraphArray(6) не пытается получить шестой абзац, а седьмой, поскольку индекс начинается с 0. Поэтому я предполагаю, что исключение выдается из этой строки кода.

Axel Richter 15.02.2023 14:52
stackoverflow.com/questions/75461377/…
Jeet 15.02.2023 15:47

@AxelRichter- Программа работает нормально, если я укажу 0 вместо 6 tableRowThree.getCell(0).getParagraphArray(6). Я думаю, что абзац 0 обязателен для предоставления, поскольку неясно, как слово обрабатывает абзацы.

Jeet 15.02.2023 16:57

Другие вопросы по теме