Установка ширины столбца таблицы в XWPFTableCell (docx)
Я генерирую файл DOCX с Apache-Poi. В wordfile я добавляю таблицы, столбцы которых имеют ширину, которую я хотел бы видеть фиксированной.
В настоящее время я использую технику, описанную здесь: http://apache-poi.1045710.n5.nabble.com/Is-there-a-way-to-set-the-width-of-a-column-in-XWPFTableCell -td5711491.html
В основном это влечет за собой установку
cell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(cols[j]));
на каждой ячейке этого столбца.
Проблема в том, что, хотя файл прекрасно открывается в MS Word, open office по-разному интерпретирует значения, установленные для ширины столбца. Принимая во внимание, что MS Word, по-видимому, принимает 20-ю точку в качестве единиц, при открытии офиса кажется, что вместо них используются точки, и поэтому все столбцы становятся в 20 раз шире, когда я открываю сгенерированный документ в ОО.
Обычно, когда я вижу что-то странное в сгенерированном выводе, я распаковываю файл docx, вижу значение и меняю свой код. Но кажется, что open office не может сохранить в docx, поэтому я не могу изменить значение в OO, сохранить его обратно и посмотреть, правильно ли Word интерпретирует документ, чтобы найти решение для нескольких приложений.
Любая идея, как я устанавливаю ширину столбца таблицы, чтобы и OO, и MS Wordt интерпретировали это одинаково?
Ответы
Ответ 1
Ответ извлечен из вопроса:
Недавно мне было указано, что LibreOffice может сэкономить до docx. Меняя сгенерированный файл и сохраняя его обратно и декомпилируя результат, я смог решить проблему.
Ключ должен сначала ввести явную ширину в таблицу. Word, похоже, не заботится о его присутствии, и OpenOffice/LibreOffice могут правильно отображать таблицу.
Итак, после создания таблицы я сделал следующее:
CTTblWidth width = table.getCTTbl().addNewTblPr().addNewTblW();
width.setType(STTblWidth.DXA);
width.setW(BigInteger.valueOf(9072));
Ответ 2
Не касайтесь отдельных ячеек.
Добавить GRID:
XWPFDocument doc = new XWPFDocument();
XWPFTable table = doc.createTable(1,2);
table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(6000));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(2000));
table.getRow(0).getCell(0).setText("1A");
table.getRow(0).getCell(1).setText("1B");
XWPFTableRow newrow = table.createRow();
newrow.getCell(0).setText("2A");
newrow.getCell(1).setText("2B");
Сетка устанавливает ширину для целых столбцов. Вам не нужно делать какие-либо циклы, чтобы установить ширину для каждой ячейки. Он работает в LibreOffice и GoogleDocs.
Чтобы просмотреть установленную ширину в MS Word, вы можете установить ширину ячеек в первой строке:
widthCellsAcrossRow(table, 0, 0, 4000);
widthCellsAcrossRow(table, 0, 0, 5000);
private static void widthCellsAcrossRow (XWPFTable table, int rowNum, int colNum, int width) {
XWPFTableCell cell = table.getRow(rowNum).getCell(colNum);
if (cell.getCTTc().getTcPr() == null)
cell.getCTTc().addNewTcPr();
if (cell.getCTTc().getTcPr().getTcW()==null)
cell.getCTTc().getTcPr().addNewTcW();
cell.getCTTc().getTcPr().getTcW().setW(BigInteger.valueOf((long) width));
}
Ответ 3
После создания таблицы макет по умолчанию устанавливается на "авто", поэтому ширина ячейки всегда увеличивается, чтобы соответствовать длине строки. По разметке OpenXML это выглядит так:
w:tblPr
w:tblLayout w:type="auto"
решение состоит в том, чтобы установить макет на fixed и задать отдельную длину столбца
w:tblPr
w:tblLayout w:type="fixed"
Здесь код poi для настройки макета таблицы:
XWPFTable table = document.createTable();
CTTblLayoutType type = table.getCTTbl().getTblPr().addNewTblLayout();
type.setType(STTblLayoutType.FIXED);
Здесь, как установить индивидуальную ширину:
int[] cols = {
4896,
1872,
4032,
1728,
1440
};
for (int i = 0; i < table.getNumberOfRows(); i++) {
XWPFTableRow row = table.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(cols[j]));
}
}
Длина столбцов равна двадцатым точкам (dxa) или 1/1440 дюйма.
Ответ 4
Это важный и очень сложный элемент. Я решил это, используя этот собственный общий метод установки ширины ячейки таблицы.
private static void setTableColumnWidths(XWPFTable table) {
table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(2000));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(3200));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1000));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1000));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1105));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1105));
}
Ответ 5
На основании других ответов...
public static void setTableColumnsWidth(XWPFTable table, long... widths) {
CTTblGrid grid = table.getCTTbl().addNewTblGrid();
for (long w : widths) {
grid.addNewGridCol().setW(BigInteger.valueOf(w));
}
}
Использование:
setTableColumnsWidth(table, 1440, 2700, 3000, 1440);