Я разбираю 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));
}
}
Как мне выйти из этой проблемы? Сгенерированный текстовый документ выглядит так уродливо из-за этой структуры вложенных таблиц.
Вопрос, который вы связали, был о том, как вставить таблицу в ячейку таблицы в таблице 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), поскольку первый устанавливает внутреннее поле ширины ячейки, а второй полагается на наличие этого поля и терпит неудачу, если его нет.
Результат выглядит так для меня:
@Jeet: мой код завершен, протестирован и работает без исключений. Значит, вы используете код, отличный от моего. Это не то, что можно обсуждать в комментариях. Пожалуйста, задайте вопрос об этой проблеме и предоставьте полный код, необходимый для воспроизведения этой проблемы.
@Jeet: «Должен ли абзац всегда быть равен 0, чтобы вставить вложенную таблицу?» Нет. Это должен быть существующий абзац. Кстати: tableRowThree.getCell(0).getParagraphArray(6) не пытается получить шестой абзац, а седьмой, поскольку индекс начинается с 0. Поэтому я предполагаю, что исключение выдается из этой строки кода.
@AxelRichter- Программа работает нормально, если я укажу 0 вместо 6 tableRowThree.getCell(0).getParagraphArray(6). Я думаю, что абзац 0 обязателен для предоставления, поскольку неясно, как слово обрабатывает абзацы.
Большое спасибо за помощь! Иногда я получаю индекс "IndexOutOfBoundsException": 6, размер: 1..... в строке -- XWPFTable tableTwo = tablerow.getCell(0).insertNewTbl(paragraph.getCTP().newCursor()); Объект абзаца здесь действителен. Индекс равен 6, что также хорошо, так как я хочу создать таблицу в 6-м абзаце. ---- Параграф XWPFParagraphnestedtable = tableRowThree.getCell(0).getParagraphArray(6);... все еще почему отображается это исключение? Должен ли абзац всегда быть 0, чтобы вставить вложенную таблицу? могут ли быть другие абзацы перед абзацем вложенной таблицы?