/thirdparties-extension/org.apache.poi.xwpf.converter.core/src/main/java/org/apache/poi/xwpf/converter/core/utils/XWPFTableUtil.java
Java | 438 lines | 329 code | 45 blank | 64 comment | 62 complexity | a478f187fe2341e51a7f5e2902591fe7 MD5 | raw file
- /**
- * Copyright (C) 2011-2012 The XDocReport Team <xdocreport@googlegroups.com>
- *
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- package org.apache.poi.xwpf.converter.core.utils;
- import static org.apache.poi.xwpf.converter.core.utils.DxaUtil.dxa2points;
- import java.awt.Color;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import org.apache.poi.xwpf.converter.core.TableCellBorder;
- import org.apache.poi.xwpf.converter.core.TableWidth;
- import org.apache.poi.xwpf.usermodel.XWPFTable;
- import org.apache.poi.xwpf.usermodel.XWPFTableCell;
- import org.apache.poi.xwpf.usermodel.XWPFTableRow;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShortHexNumber;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
- 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.CTTrPr;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
- import org.w3c.dom.Attr;
- import org.w3c.dom.Node;
- public class XWPFTableUtil
- {
- private static final String MAIN_NAMESPACE = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
- // Hexa Bitmask for tblLook.
- public static final int DEFAULT_TBLLOOK = 0x0000;
- public static final int APPLY_FIRST_ROW_CONDITIONNAL_FORMATTING = 0x0020; // Apply first row conditional formatting
- public static final int APPLY_LAST_ROW_CONDITIONNAL_FORMATTING = 0x0040; // Apply last row conditional formatting
- public static final int APPLY_FIRST_COLUMN_CONDITIONNAL_FORMATTING = 0x0080; // Apply first column conditional
- // formatting
- public static final int APPLY_LAST_COLUMN_CONDITIONNAL_FORMATTING = 0x0100; // Apply last column conditional
- // formatting
- public static final int DO_NOT_APPLY_ROW_BANDING_CONDITIONNAL_FORMATTING = 0x0200; // Do not apply row banding
- // conditional formatting
- public static final int DO_NOT_APPLY_COLUMN_BANDING_CONDITIONNAL_FORMATTING = 0x0400; // Do not apply column banding
- // conditional formatting
- /**
- * Compute column widths of the XWPF table.
- *
- * @param table
- * @return
- */
- public static float[] computeColWidths( XWPFTable table )
- {
- XWPFTableRow firstRow = getFirstRow( table );
- float[] colWidths;
- // Get first row to know if there is cell which have gridSpan to compute
- // columns number.
- int nbCols = getNumberOfColumns( firstRow );
- // Compare nbCols computed with number of grid colList
- CTTblGrid grid = table.getCTTbl().getTblGrid();
- List<CTTblGridCol> cols = grid.getGridColList();
- if ( nbCols > cols.size() )
- {
- Collection<Float> maxColWidths = null;
- Collection<Float> currentColWidths = null;
- // nbCols computed is not equals to number of grid colList
- // columns width must be computed by looping for each row/cells
- List<XWPFTableRow> rows = table.getRows();
- for ( XWPFTableRow row : rows )
- {
- currentColWidths = computeColWidths( row );
- if ( maxColWidths == null )
- {
- maxColWidths = currentColWidths;
- }
- else
- {
- if ( currentColWidths.size() > maxColWidths.size() )
- {
- maxColWidths = currentColWidths;
- }
- }
- }
- colWidths = new float[maxColWidths.size()];
- int i = 0;
- for ( Float colWidth : maxColWidths )
- {
- colWidths[i++] = colWidth;
- }
- return colWidths;
- }
- else
- {
- // If w:gridAfter is defined, ignore the last columns defined on the gridColumn
- int nbColumnsToIgnoreBefore = getNbColumnsToIgnore( firstRow, true );
- int nbColumnsToIgnoreAfter = getNbColumnsToIgnore( firstRow, false );
- int nbColumns = cols.size() - nbColumnsToIgnoreBefore - nbColumnsToIgnoreAfter;
- // nbCols computed is equals to number of grid colList
- // columns width can be computed by using the grid colList
- colWidths = new float[nbColumns];
- float colWidth = -1;
- for ( int i = nbColumnsToIgnoreBefore; i < colWidths.length; i++ )
- {
- CTTblGridCol tblGridCol = cols.get( i );
- colWidth = tblGridCol.getW().floatValue();
- colWidths[i] = dxa2points( colWidth );
- }
- }
- return colWidths;
- }
- private static int getNbColumnsToIgnore( XWPFTableRow row, boolean before )
- {
- CTTrPr trPr = row.getCtRow().getTrPr();
- if ( trPr == null )
- {
- return 0;
- }
- List<CTDecimalNumber> gridBeforeAfters = before ? trPr.getGridBeforeList() : trPr.getGridAfterList();
- if ( gridBeforeAfters == null || gridBeforeAfters.size() < 1 )
- {
- return 0;
- }
- int nbColumns = 0;
- BigInteger val = null;
- for ( CTDecimalNumber gridBeforeAfter : gridBeforeAfters )
- {
- val = gridBeforeAfter.getVal();
- if ( val != null )
- {
- nbColumns += val.intValue();
- }
- }
- return nbColumns;
- }
- /**
- * Returns number of column if the XWPF table by using the declared cell (which can declare gridSpan) from the first
- * row.
- *
- * @param table
- * @return
- */
- public static int getNumberOfColumns( XWPFTableRow row )
- {
- if ( row == null )
- {
- return 0;
- }
- // Get first row to know if there is cell which have gridSpan to compute
- // columns number.
- int nbCols = 0;
- List<XWPFTableCell> tableCellsOffFirstRow = row.getTableCells();
- for ( XWPFTableCell tableCellOffFirstRow : tableCellsOffFirstRow )
- {
- CTDecimalNumber gridSpan = getGridSpan( tableCellOffFirstRow );
- if ( gridSpan != null )
- {
- nbCols += gridSpan.getVal().intValue();
- }
- else
- {
- nbCols += 1;
- }
- }
- return nbCols;
- }
- public static XWPFTableRow getFirstRow( XWPFTable table )
- {
- int numberOfRows = table.getNumberOfRows();
- if ( numberOfRows > 0 )
- {
- return table.getRow( 0 );
- }
- return null;
- }
- public static CTDecimalNumber getGridSpan( XWPFTableCell cell )
- {
- if ( cell.getCTTc().getTcPr() != null )
- return cell.getCTTc().getTcPr().getGridSpan();
- return null;
- }
- public static CTTblWidth getWidth( XWPFTableCell cell )
- {
- return cell.getCTTc().getTcPr().getTcW();
- }
- private static Collection<Float> computeColWidths( XWPFTableRow row )
- {
- List<Float> colWidths = new ArrayList<Float>();
- List<XWPFTableCell> cells = row.getTableCells();
- for ( XWPFTableCell cell : cells )
- {
- // Width
- CTTblWidth width = getWidth( cell );
- if ( width != null )
- {
- int nb = 1;
- CTDecimalNumber gridSpan = getGridSpan( cell );
- TableWidth tableCellWidth = getTableWidth( cell );
- if ( gridSpan != null )
- {
- nb = gridSpan.getVal().intValue();
- }
- for ( int i = 0; i < nb; i++ )
- {
- colWidths.add( tableCellWidth.width / nb );
- }
- }
- }
- return colWidths;
- }
- /**
- * Returns table width of teh XWPF table.
- *
- * @param table
- * @return
- */
- public static TableWidth getTableWidth( XWPFTable table )
- {
- float width = 0;
- boolean percentUnit = false;
- CTTblPr tblPr = table.getCTTbl().getTblPr();
- if ( tblPr.isSetTblW() )
- {
- CTTblWidth tblWidth = tblPr.getTblW();
- return getTableWidth( tblWidth );
- }
- return new TableWidth( width, percentUnit );
- }
- public static TableWidth getTableWidth( XWPFTableCell cell )
- {
- float width = 0;
- boolean percentUnit = false;
- CTTcPr tblPr = cell.getCTTc().getTcPr();
- if ( tblPr.isSetTcW() )
- {
- CTTblWidth tblWidth = tblPr.getTcW();
- return getTableWidth( tblWidth );
- }
- return new TableWidth( width, percentUnit );
- }
- public static TableWidth getTableWidth( CTTblWidth tblWidth )
- {
- float width = tblWidth.getW().intValue();
- boolean percentUnit = ( STTblWidth.INT_PCT == tblWidth.getType().intValue() );
- if ( percentUnit )
- {
- width = width / 100f;
- }
- else
- {
- width = dxa2points( width );
- }
- return new TableWidth( width, percentUnit );
- }
- public static CTTblPr getTblPr( XWPFTable table )
- {
- CTTbl tbl = table.getCTTbl();
- if ( tbl != null )
- {
- return tbl.getTblPr();
- }
- return null;
- }
- public static CTTblBorders getTblBorders( XWPFTable table )
- {
- CTTblPr tblPr = getTblPr( table );
- if ( tblPr != null )
- {
- return tblPr.getTblBorders();
- }
- return null;
- }
- public static CTTblCellMar getTblCellMar( XWPFTable table )
- {
- CTTblPr tblPr = getTblPr( table );
- if ( tblPr != null )
- {
- return tblPr.getTblCellMar();
- }
- return null;
- }
- public static TableCellBorder getTableCellBorder( CTBorder border, boolean fromTableCell )
- {
- if ( border != null )
- {
- boolean noBorder = ( STBorder.NONE == border.getVal() || STBorder.NIL == border.getVal() );
- if ( noBorder )
- {
- return new TableCellBorder( !noBorder, fromTableCell );
- }
- Float borderSize = null;
- BigInteger size = border.getSz();
- if ( size != null )
- {
- // http://officeopenxml.com/WPtableBorders.php
- // if w:sz="4" => 1/4 points
- borderSize = size.floatValue() / 8f;
- }
- Color borderColor = ColorHelper.getBorderColor( border );
- return new TableCellBorder( borderSize, borderColor, fromTableCell );
- }
- return null;
- }
- public static Color getBorderColor( CTBorder border )
- {
- if ( border == null )
- {
- return null;
- }
- // border.getColor returns object???, use attribute w:color to get
- // the color.
- Node colorAttr = border.getDomNode().getAttributes().getNamedItemNS( MAIN_NAMESPACE, "color" );
- if ( colorAttr != null )
- {
- Object val = border.getVal();
- return ColorHelper.getColor( ( (Attr) colorAttr ).getValue(), val, false );
- }
- return null;
- }
- public static CTShortHexNumber getTblLook( XWPFTable table )
- {
- CTTblPr tblPr = getTblPr( table );
- if ( tblPr != null )
- {
- return tblPr.getTblLook();
- }
- return null;
- }
- public static int getTblLookVal( XWPFTable table )
- {
- int tblLook = DEFAULT_TBLLOOK;
- CTShortHexNumber hexNumber = getTblLook( table );
- if ( hexNumber != null && !hexNumber.isNil() )
- {
- // CTShortHexNumber#getVal() returns byte[] and not byte, use attr value ???
- Attr attr = (Attr) hexNumber.getDomNode().getAttributes().getNamedItemNS( MAIN_NAMESPACE, "val" );
- if ( attr != null )
- {
- String value = attr.getValue();
- try
- {
- tblLook = Integer.parseInt( value, 16 );
- }
- catch ( Throwable e )
- {
- e.printStackTrace();
- }
- }
- }
- return tblLook;
- }
- public static boolean canApplyFirstRow( int tblLookVal )
- {
- int mask = APPLY_FIRST_ROW_CONDITIONNAL_FORMATTING;
- return ( tblLookVal & mask ) == mask;
- }
- public static boolean canApplyLastRow( int tblLookVal )
- {
- int mask = APPLY_LAST_ROW_CONDITIONNAL_FORMATTING;
- return ( tblLookVal & mask ) == mask;
- }
- public static boolean canApplyFirstCol( int tblLookVal )
- {
- int mask = APPLY_FIRST_COLUMN_CONDITIONNAL_FORMATTING;
- return ( tblLookVal & mask ) == mask;
- }
- public static boolean canApplyLastCol( int tblLookVal )
- {
- int mask = APPLY_LAST_COLUMN_CONDITIONNAL_FORMATTING;
- return ( tblLookVal & mask ) == mask;
- }
- }