All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.poi.xwpf.converter.core.utils.XWPFTableUtil Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
/**
 * 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

    /**
     * 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 = grid.getGridColList();
        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;
    }

    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 )
    {
        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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy