All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.poi.xwpf.converter.core.utils.XWPFTableUtil Maven / Gradle / Ivy
/**
* Copyright (C) 2011-2012 The XDocReport Team
*
* 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
public static float[] computeColWidths( CTTbl table )
{
CTTblGrid grid = table.getTblGrid();
List cols = getGridColList( grid );
int nbColumns = cols.size();
float[] colWidths = new float[nbColumns];
float colWidth = -1;
int nbColumnsToIgnoreBefore = 0;
for ( int i = nbColumnsToIgnoreBefore; i < colWidths.length; i++ )
{
CTTblGridCol tblGridCol = cols.get( i );
colWidth = tblGridCol.getW().floatValue();
colWidths[i] = dxa2points( colWidth );
}
return colWidths;
}
/**
* 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 cols = getGridColList( grid );
if ( nbCols > cols.size() )
{
Collection maxColWidths = null;
Collection currentColWidths = null;
// nbCols computed is not equals to number of grid colList
// columns width must be computed by looping for each row/cells
List 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;
}
/**
*
* Ex : should be ignored. See https://code.google.com/p/xdocreport/issues/detail?id=315
*
*
* @param grid
* @return
*/
private static List getGridColList( CTTblGrid grid )
{
List newCols = new ArrayList();
List cols = grid.getGridColList();
for ( CTTblGridCol col : cols )
{
if ( col.getW().floatValue() >= 0 )
{
newCols.add( col );
}
}
return newCols;
}
private static int getNbColumnsToIgnore( XWPFTableRow row, boolean before )
{
CTTrPr trPr = row.getCtRow().getTrPr();
if ( trPr == null )
{
return 0;
}
List 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 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 computeColWidths( XWPFTableRow row )
{
List colWidths = new ArrayList();
List 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 )
{
if ( tblWidth == null )
{
return null;
}
Float width = getTblWidthW( tblWidth );
if ( width == null )
{
return null;
}
boolean percentUnit = ( STTblWidth.INT_PCT == tblWidth.getType().intValue() );
if ( percentUnit )
{
width = width / 100f;
}
else
{
width = dxa2points( width );
}
return new TableWidth( width, percentUnit );
}
/**
* Returns the float value of
*
* @param tblWidth
* @return
*/
public static Float getTblWidthW( CTTblWidth tblWidth )
{
try
{
return tblWidth.getW().floatValue();
}
catch ( Throwable e )
{
// Sometimes w:w is a float value.Ex :
// see https://code.google.com/p/xdocreport/issues/detail?id=315
Attr attr =
(Attr) tblWidth.getDomNode().getAttributes().getNamedItemNS( "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
"w" );
if ( attr != null )
{
return Float.valueOf( attr.getValue() );
}
}
return null;
}
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;
}
}