java - para - Establecer el ancho de columna de una tabla en XWPFTableCell(docx)
descargar libreria apache poi para netbeans (4)
Estoy generando un archivo docx con apache-poi. En el archivo de palabras, agrego tablas, cuyas columnas tienen un ancho que me gustaría ver fijo.
Actualmente, utilizo la técnica que se describe aquí: http://apache-poi.1045710.n5.nabble.com/Is- there-a - way - to - set- the- width - of-a - column - in - XWPFTableCell -td5711491.html
Básicamente, esto implica establecer
cell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(cols[j]));
en cada celda de esa columna.
El problema es que mientras el archivo se abre perfectamente en MS Word, Open Office interpreta los valores que establezco en el ancho de columna de manera diferente. Mientras que MS Word aparentemente asume el 20 ° de un punto como unidades, Open Office parece usar puntos en su lugar y, por lo tanto, todas las columnas son 20 veces más amplias cuando abro el documento generado en OO.
Por lo general, cuando veo algo extraño en la salida generada, descomprimo el archivo docx, veo cuál debe ser el valor y cambio mi código. Pero la oficina abierta no parece poder guardar en docx, así que no puedo cambiar el valor en OO, guardarlo de nuevo y ver si Word todavía interpreta el documento correctamente para encontrar una solución de aplicación cruzada.
¿Alguna idea de cómo configuro el ancho de la columna de la tabla para que tanto OO como MS Wordt lo interpreten de la misma manera?
No toque celdas individuales. Agrega una 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");
La grilla establece anchos para columnas enteras. No necesita hacer ningún ciclo para establecer un ancho para cada celda. Funciona en LibreOffice y GoogleDocs.
Para ver el ancho indicado en MS Word también, puede establecer el ancho de las celdas en la primera fila:
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));
}
Respuesta extraída de la pregunta:
Recientemente se me indicó que LibreOffice puede guardar en docx. Al cambiar el archivo generado y guardarlo de nuevo y descompilar el resultado, he podido resolver el problema.
La clave es poner primero un ancho explícito a la tabla. A Word no parece importarle su presencia, y OpenOffice / LibreOffice pueden representar la tabla correctamente.
Entonces, después de la creación de la tabla, hice lo siguiente:
CTTblWidth width = table.getCTTbl().addNewTblPr().addNewTblW();
width.setType(STTblWidth.DXA);
width.setW(BigInteger.valueOf(9072));
Tras la creación de la tabla, el diseño se establece en "auto" por defecto, por lo tanto, el ancho de la celda siempre aumentará para seguir la longitud de la cadena. Según el marcado OpenXML, parece que w:tblPr w:tblLayout w:type="auto"
la solución es establecer el diseño en arreglado y establecer la longitud de la columna individual w:tblPr w:tblLayout w:type="fixed"
Aquí está el código poi para configurar el diseño de la tabla:
XWPFTable table = document.createTable();
CTTblLayoutType type = table.getCTTbl().getTblPr().addNewTblLayout();
type.setType(STTblLayoutType.FIXED);
A continuación, se explica cómo configurar el ancho individual:
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]));
}
}
las longitudes de las columnas son en vigésimas partes de un punto (dxa) o 1/1440 pulgadas.
Este es un elemento importante y muy complicado. Lo resolví usando este método genérico propio para establecer los anchos de una celda de tabla.
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));
}