com.deepoove.poi.util.TableTools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of poi-tl Show documentation
Show all versions of poi-tl Show documentation
Generate word(docx) with template
/*
* Copyright 2014-2021 Sayi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.deepoove.poi.util;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import org.apache.poi.xwpf.usermodel.BodyType;
import org.apache.poi.xwpf.usermodel.TableWidthType;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTable.XWPFBorderType;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblLayoutType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblLayoutType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.data.style.CellStyle;
import com.deepoove.poi.data.style.RowStyle;
import com.deepoove.poi.data.style.TableStyle;
import com.deepoove.poi.xwpf.BodyContainer;
import com.deepoove.poi.xwpf.BodyContainerFactory;
/**
* XWPFTable Tools
*
* @author Sayi
* @version 1.4.0
*/
public final class TableTools {
/**
* merge several columns of cells in the same row
*
* @param table table
* @param row index of the row
* @param fromCol from column to be merged
* @param toCol to column to be merged
*/
public static void mergeCellsHorizonal(XWPFTable table, int row, int fromCol, int toCol) {
Preconditions.requireGreaterThan(toCol, fromCol, "To column to be merged must greater than from column.");
mergeCellsHorizontalWithoutRemove(table, row, fromCol, toCol);
XWPFTableRow rowTable = table.getRow(row);
for (int colIndex = fromCol + 1; colIndex <= toCol; colIndex++) {
rowTable.removeCell(fromCol + 1);
if (rowTable.getTableCells().size() != rowTable.getCtRow().sizeOfTcArray()) {
rowTable.getCtRow().removeTc(fromCol + 1);
}
}
}
/**
* merge several columns of cells in the same row, but do'not remove extra cells
*
* @param table table
* @param row index of the row
* @param fromCol from column to be merged
* @param toCol to column to be merged
*/
public static void mergeCellsHorizontalWithoutRemove(XWPFTable table, int row, int fromCol, int toCol) {
Preconditions.requireGreaterThan(toCol, fromCol, "To column to be merged must greater than from column.");
XWPFTableCell cell = table.getRow(row).getCell(fromCol);
CTTcPr tcPr = getTcPr(cell);
tcPr.addNewGridSpan();
tcPr.getGridSpan().setVal(BigInteger.valueOf((long) (toCol - fromCol + 1)));
int tcw = 0;
for (int colIndex = fromCol; colIndex <= toCol; colIndex++) {
XWPFTableCell tableCell = table.getRow(row).getCell(colIndex);
// TODO pct, auto
if (TableWidthType.DXA == tableCell.getWidthType()) {
if (-1 == tableCell.getWidth()) return;
tcw += tableCell.getWidth();
} else {
return;
}
}
if (0 != tcw) cell.setWidth(tcw + "");
}
/**
* merge several rows of cells in the same column
*
* @param table table
* @param col index of the column
* @param fromRow from row to be merged
* @param toRow end row to be merged
*/
public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
Preconditions.requireGreaterThan(toRow, fromRow, "To row to be merged must greater than from row.");
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
CTTcPr tcPr = getTcPr(cell);
CTVMerge vMerge = tcPr.addNewVMerge();
if (rowIndex == fromRow) {
// The first merged cell is set with RESTART merge value
vMerge.setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
vMerge.setVal(STMerge.CONTINUE);
}
}
}
/**
* set table width
*
* @param table
* @param width
* @param colWidths
*/
public static void setWidth(XWPFTable table, String width, int[] colWidths) {
ensureTblW(table);
table.setWidth(width);
if (null == colWidths) {
int columnSize = TableTools.obtainColumnSize(table);
if (table.getWidthType() == TableWidthType.DXA) {
colWidths = UnitUtils.average(Integer.valueOf(width), columnSize);
} else if (table.getWidthType() == TableWidthType.PCT) {
int sum = 0;
colWidths = new int[columnSize];
for (int i = 0; i < columnSize - 1; i++) {
colWidths[i] = 100 / columnSize;
sum += colWidths[i];
}
colWidths[columnSize - 1] = 100 - sum;
}
}
if (null != colWidths) {
BigInteger[] gridCol = null;
String[] cellWidth = null;
if (table.getWidthType() == TableWidthType.DXA) {
cellWidth = Arrays.stream(colWidths).mapToObj(String::valueOf).toArray(String[]::new);
gridCol = Arrays.stream(colWidths).mapToObj(BigInteger::valueOf).toArray(BigInteger[]::new);
} else if (table.getWidthType() == TableWidthType.PCT) {
cellWidth = Arrays.stream(colWidths).mapToObj(w -> w + "%").toArray(String[]::new);
BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(table.getBody());
int pageWidth = bodyContainer.elementPageWidth(table);
int tableWidth = pageWidth * Integer.valueOf(width.substring(0, width.length() - 1)) / 100;
gridCol = Arrays.stream(colWidths)
.mapToObj(w -> BigInteger.valueOf(w * tableWidth / 100))
.toArray(BigInteger[]::new);
}
CTTblGrid tblGrid = TableTools.getTblGrid(table);
CTTblLayoutType tblLayout = TableTools.getTblLayout(table);
tblLayout.setType(STTblLayoutType.FIXED);
for (int index = 0; index < colWidths.length; index++) {
if (null != gridCol) {
CTTblGridCol addNewGridCol = tblGrid.addNewGridCol();
addNewGridCol.setW(gridCol[index]);
}
List rows = table.getRows();
for (XWPFTableRow row : rows) {
row.getCell(index).setWidth(cellWidth[index]);
}
}
}
}
private static void ensureTblW(XWPFTable table) {
CTTbl ctTbl = table.getCTTbl();
CTTblPr tblPr = (ctTbl.getTblPr() != null) ? ctTbl.getTblPr() : ctTbl.addNewTblPr();
if (!tblPr.isSetTblW()) tblPr.addNewTblW();
}
public static void borderTable(XWPFTable table, BorderStyle borderStyle) {
setBorder(table::setLeftBorder, borderStyle);
setBorder(table::setRightBorder, borderStyle);
setBorder(table::setTopBorder, borderStyle);
setBorder(table::setBottomBorder, borderStyle);
setBorder(table::setInsideHBorder, borderStyle);
setBorder(table::setInsideVBorder, borderStyle);
}
public static void borderTable(XWPFTable table, int size) {
CTTblPr tblPr = getTblPr(table);
CTTblBorders tblBorders = tblPr.getTblBorders();
if (null == tblBorders) {
tblBorders = tblPr.addNewTblBorders();
}
BigInteger borderSize = BigInteger.valueOf(size);
if (!tblBorders.isSetBottom()) tblBorders.addNewBottom();
if (!tblBorders.isSetLeft()) tblBorders.addNewLeft();
if (!tblBorders.isSetTop()) tblBorders.addNewTop();
if (!tblBorders.isSetRight()) tblBorders.addNewRight();
if (!tblBorders.isSetInsideH()) tblBorders.addNewInsideH();
if (!tblBorders.isSetInsideV()) tblBorders.addNewInsideV();
tblBorders.getBottom().setSz(borderSize);
tblBorders.getLeft().setSz(borderSize);
tblBorders.getTop().setSz(borderSize);
tblBorders.getRight().setSz(borderSize);
tblBorders.getInsideH().setSz(borderSize);
tblBorders.getInsideV().setSz(borderSize);
}
/**
* set border style
*
* TableTools.setBorder(table::setLeftBorder, border);
*
*
* @param consumer
* @param border
*/
public static void setBorder(FourthConsumer consumer,
BorderStyle border) {
if (null != border) consumer.accept(border.getType(), border.getSize(), 0, border.getColor());
}
public static void initBasicTable(XWPFTable table, int col, float width, TableStyle style) {
int defaultBorderSize = 4;
widthTable(table, width, col);
borderTable(table, defaultBorderSize);
styleTable(table, style);
}
public static boolean isInsideTable(XWPFRun run) {
return ((XWPFParagraph) run.getParent()).getPartType() == BodyType.TABLECELL;
}
public static void styleTable(XWPFTable table, TableStyle style) {
StyleUtils.styleTable(table, style);
}
public static void styleTableRow(XWPFTableRow row, RowStyle rowStyle) {
StyleUtils.styleTableRow(row, rowStyle);
}
public static void styleTableCell(XWPFTableCell cell, CellStyle cellStyle) {
StyleUtils.styleTableCell(cell, cellStyle);
}
public static int obtainRowSize(XWPFTable table) {
return table.getRows().size();
}
public static int obtainColumnSize(XWPFTable table) {
return table.getRows().get(0).getTableCells().size();
}
public static CTTblGrid getTblGrid(XWPFTable table) {
CTTblGrid tblGrid = table.getCTTbl().getTblGrid();
if (null == tblGrid) {
tblGrid = table.getCTTbl().addNewTblGrid();
}
return tblGrid;
}
public static CTTblLayoutType getTblLayout(XWPFTable table) {
CTTblPr tblPr = getTblPr(table);
return tblPr.isSetTblLayout() ? tblPr.getTblLayout() : tblPr.addNewTblLayout();
}
private static CTTblPr getTblPr(XWPFTable table) {
CTTblPr tblPr = table.getCTTbl().getTblPr();
if (null == tblPr) {
tblPr = table.getCTTbl().addNewTblPr();
}
return tblPr;
}
public static CTTcPr getTcPr(XWPFTableCell cell) {
CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
return tcPr;
}
@Deprecated
public static void widthTable(XWPFTable table, float[] colWidths) {
float widthCM = 0;
for (float w : colWidths) {
widthCM += w;
}
int width = UnitUtils.cm2Twips(widthCM);
CTTblPr tblPr = getTblPr(table);
CTTblWidth tblW = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
tblW.setType(0 == width ? STTblWidth.AUTO : STTblWidth.DXA);
tblW.setW(BigInteger.valueOf(width));
if (0 != width) {
CTTblGrid tblGrid = getTblGrid(table);
for (float w : colWidths) {
CTTblGridCol addNewGridCol = tblGrid.addNewGridCol();
addNewGridCol.setW(BigInteger.valueOf(UnitUtils.cm2Twips(w)));
}
}
}
@Deprecated
public static void widthTable(XWPFTable table, float widthCM, int cols) {
int width = UnitUtils.cm2Twips(widthCM);
CTTblPr tblPr = getTblPr(table);
CTTblWidth tblW = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
tblW.setType(0 == width ? STTblWidth.AUTO : STTblWidth.DXA);
tblW.setW(BigInteger.valueOf(width));
if (0 != width) {
CTTblGrid tblGrid = getTblGrid(table);
for (int j = 0; j < cols; j++) {
CTTblGridCol addNewGridCol = tblGrid.addNewGridCol();
addNewGridCol.setW(BigInteger.valueOf(width / cols));
}
}
}
}