]> source.dussan.org Git - poi.git/commitdiff
fix styles output;
authorSergey Vladimirov <sergey@apache.org>
Wed, 13 Jul 2011 17:10:13 +0000 (17:10 +0000)
committerSergey Vladimirov <sergey@apache.org>
Wed, 13 Jul 2011 17:10:13 +0000 (17:10 +0000)
add columns and rows headers (optional, on by default);
output sheet headers as h2, not as h1;
output columns widths.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1146142 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java
src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlUtils.java
src/scratchpad/src/org/apache/poi/hwpf/converter/HtmlDocumentFacade.java

index 7377ba3bba4f74045c12a9331fb844f9d2ab8418..99cf70c931961d68b6a87f5ab18408448a21fe29 100644 (file)
@@ -123,6 +123,10 @@ public class ExcelToHtmlConverter
 
     private final HtmlDocumentFacade htmlDocumentFacade;
 
+    private boolean outputColumnHeaders = true;
+
+    private boolean outputRowNumbers = true;
+
     private final Element styles;
 
     private final Set<Short> usedStyles = new LinkedHashSet<Short>();
@@ -249,11 +253,42 @@ public class ExcelToHtmlConverter
         }
     }
 
+    /**
+     * Generates name for output as column header in case
+     * <tt>{@link #isOutputColumnHeaders()} == true</tt>
+     * 
+     * @param columnIndex
+     *            0-based column index
+     */
+    protected String getColumnName( int columnIndex )
+    {
+        return String.valueOf( columnIndex + 1 );
+    }
+
     public Document getDocument()
     {
         return htmlDocumentFacade.getDocument();
     }
 
+    /**
+     * Generates name for output as row number in case
+     * <tt>{@link #isOutputRowNumbers()} == true</tt>
+     */
+    private String getRowName( HSSFRow row )
+    {
+        return String.valueOf( row.getRowNum() + 1 );
+    }
+
+    public boolean isOutputColumnHeaders()
+    {
+        return outputColumnHeaders;
+    }
+
+    public boolean isOutputRowNumbers()
+    {
+        return outputRowNumbers;
+    }
+
     protected boolean processCell( HSSFCell cell, Element tableCellElement )
     {
         final HSSFCellStyle cellStyle = cell.getCellStyle();
@@ -348,6 +383,52 @@ public class ExcelToHtmlConverter
         return ExcelToHtmlUtils.isEmpty( value ) && cellStyleIndex == 0;
     }
 
+    protected void processColumnHeaders( int maxSheetColumns, Element table )
+    {
+        Element tableHeader = htmlDocumentFacade.createTableHeader();
+        table.appendChild( tableHeader );
+
+        Element tr = htmlDocumentFacade.createTableRow();
+
+        if ( isOutputRowNumbers() )
+        {
+            // empty row at left-top corner
+            tr.appendChild( htmlDocumentFacade.createTableHeaderCell() );
+        }
+
+        for ( int c = 0; c < maxSheetColumns; c++ )
+        {
+            Element th = htmlDocumentFacade.createTableHeaderCell();
+            String text = getColumnName( c );
+            th.appendChild( htmlDocumentFacade.createText( text ) );
+            tr.appendChild( th );
+        }
+        tableHeader.appendChild( tr );
+    }
+
+    /**
+     * Creates COLGROUP element with width specified for all columns. (Except
+     * first if <tt>{@link #isOutputRowNumbers()}==true</tt>)
+     */
+    protected void processColumnWidths( HSSFSheet sheet, int maxSheetColumns,
+            Element table )
+    {
+        // draw COLS after we know max column number
+        Element columnGroup = htmlDocumentFacade.createTableColumnGroup();
+        if ( isOutputRowNumbers() )
+        {
+            columnGroup.appendChild( htmlDocumentFacade.createTableColumn() );
+        }
+        for ( int c = 0; c < maxSheetColumns; c++ )
+        {
+            Element col = htmlDocumentFacade.createTableColumn();
+            col.setAttribute( "width", String.valueOf( ExcelToHtmlUtils
+                    .getColumnWidthInPx( sheet.getColumnWidth( c ) ) ) );
+            columnGroup.appendChild( col );
+        }
+        table.appendChild( columnGroup );
+    }
+
     protected void processDocumentInformation(
             SummaryInformation summaryInformation )
     {
@@ -365,16 +446,26 @@ public class ExcelToHtmlConverter
                     .addDescription( summaryInformation.getComments() );
     }
 
-    protected boolean processRow( HSSFRow row, Element tableRowElement )
+    /**
+     * @return maximum 1-base index of column that were rendered, zero if none
+     */
+    protected int processRow( HSSFRow row, Element tableRowElement )
     {
-        boolean emptyRow = true;
-
         final short maxColIx = row.getLastCellNum();
         if ( maxColIx <= 0 )
-            return true;
+            return 0;
 
         final List<Element> emptyCells = new ArrayList<Element>( maxColIx );
 
+        if ( isOutputRowNumbers() )
+        {
+            Element tableRowNumberCellElement = htmlDocumentFacade
+                    .createTableHeaderCell();
+            processRowNumber( row, tableRowNumberCellElement );
+            emptyCells.add( tableRowNumberCellElement );
+        }
+
+        int maxRenderedColumn = 0;
         for ( int colIx = 0; colIx < maxColIx; colIx++ )
         {
             HSSFCell cell = row.getCell( colIx );
@@ -404,18 +495,24 @@ public class ExcelToHtmlConverter
                 emptyCells.clear();
 
                 tableRowElement.appendChild( tableCellElement );
-                emptyRow = false;
+                maxRenderedColumn = colIx;
             }
         }
 
-        return emptyRow;
+        return maxRenderedColumn + 1;
+    }
+
+    protected void processRowNumber( HSSFRow row,
+            Element tableRowNumberCellElement )
+    {
+        tableRowNumberCellElement.setAttribute( "class", "rownumber" );
+        Text text = htmlDocumentFacade.createText( getRowName( row ) );
+        tableRowNumberCellElement.appendChild( text );
     }
 
     protected void processSheet( HSSFSheet sheet )
     {
-        Element h1 = htmlDocumentFacade.createHeader1();
-        h1.appendChild( htmlDocumentFacade.createText( sheet.getSheetName() ) );
-        htmlDocumentFacade.getBody().appendChild( h1 );
+        processSheetHeader( htmlDocumentFacade.getBody(), sheet );
 
         final int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
         if ( physicalNumberOfRows <= 0 )
@@ -426,24 +523,24 @@ public class ExcelToHtmlConverter
 
         final List<Element> emptyRowElements = new ArrayList<Element>(
                 physicalNumberOfRows );
-
+        int maxSheetColumns = 1;
         for ( int r = 0; r < physicalNumberOfRows; r++ )
         {
             HSSFRow row = sheet.getRow( r );
 
             Element tableRowElement = htmlDocumentFacade.createTableRow();
 
-            boolean emptyRow;
+            int maxRowColumnNumber;
             if ( row != null )
             {
-                emptyRow = processRow( row, tableRowElement );
+                maxRowColumnNumber = processRow( row, tableRowElement );
             }
             else
             {
-                emptyRow = true;
+                maxRowColumnNumber = 0;
             }
 
-            if ( emptyRow )
+            if ( maxRowColumnNumber == 0 )
             {
                 emptyRowElements.add( tableRowElement );
             }
@@ -451,22 +548,37 @@ public class ExcelToHtmlConverter
             {
                 if ( !emptyRowElements.isEmpty() )
                 {
-                    for ( Element emptyCellElement : emptyRowElements )
+                    for ( Element emptyRowElement : emptyRowElements )
                     {
-                        tableBody.appendChild( emptyCellElement );
+                        tableBody.appendChild( emptyRowElement );
                     }
                     emptyRowElements.clear();
                 }
 
                 tableBody.appendChild( tableRowElement );
-                emptyRow = false;
             }
+            maxSheetColumns = Math.max( maxSheetColumns, maxRowColumnNumber );
+        }
+
+        processColumnWidths( sheet, maxSheetColumns, table );
+
+        if ( isOutputColumnHeaders() )
+        {
+            processColumnHeaders( maxSheetColumns, table );
         }
 
         table.appendChild( tableBody );
+
         htmlDocumentFacade.getBody().appendChild( table );
     }
 
+    protected void processSheetHeader( Element htmlBody, HSSFSheet sheet )
+    {
+        Element h2 = htmlDocumentFacade.createHeader2();
+        h2.appendChild( htmlDocumentFacade.createText( sheet.getSheetName() ) );
+        htmlBody.appendChild( h2 );
+    }
+
     public void processWorkbook( HSSFWorkbook workbook )
     {
         final SummaryInformation summaryInformation = workbook
@@ -476,6 +588,12 @@ public class ExcelToHtmlConverter
             processDocumentInformation( summaryInformation );
         }
 
+        for ( int s = 0; s < workbook.getNumberOfSheets(); s++ )
+        {
+            HSSFSheet sheet = workbook.getSheetAt( s );
+            processSheet( sheet );
+        }
+
         for ( short i = 0; i < workbook.getNumCellStyles(); i++ )
         {
             HSSFCellStyle cellStyle = workbook.getCellStyleAt( i );
@@ -488,11 +606,15 @@ public class ExcelToHtmlConverter
                         .createText( "td.cellstyle_" + i + "{"
                                 + buildStyle( workbook, cellStyle ) + "}\n" ) );
         }
+    }
 
-        for ( int s = 0; s < workbook.getNumberOfSheets(); s++ )
-        {
-            HSSFSheet sheet = workbook.getSheetAt( s );
-            processSheet( sheet );
-        }
+    public void setOutputColumnHeaders( boolean outputColumnHeaders )
+    {
+        this.outputColumnHeaders = outputColumnHeaders;
+    }
+
+    public void setOutputRowNumbers( boolean outputRowNumbers )
+    {
+        this.outputRowNumbers = outputRowNumbers;
     }
 }
index 3e35a716fc7cf74382f97baef573d5aa7ae95290..0131b6f30f2df309eacfbf04cd6fa636ca3476f6 100644 (file)
@@ -29,6 +29,9 @@ public class ExcelToHtmlUtils
 {
     static final String EMPTY = "";
 
+    private static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
+    private static final int UNIT_OFFSET_LENGTH = 7;
+
     public static String getBorderStyle( short xlsBorder )
     {
         final String borderStyle;
@@ -93,6 +96,23 @@ public class ExcelToHtmlUtils
         return stringBuilder.toString();
     }
 
+    /**
+     * See <a href=
+     * "http://apache-poi.1045710.n5.nabble.com/Excel-Column-Width-Unit-Converter-pixels-excel-column-width-units-td2301481.html"
+     * >here</a> for Xio explanation and details
+     */
+    public static int getColumnWidthInPx( int widthUnits )
+    {
+        int pixels = ( widthUnits / EXCEL_COLUMN_WIDTH_FACTOR )
+                * UNIT_OFFSET_LENGTH;
+
+        int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;
+        pixels += Math.round( offsetWidthUnits
+                / ( (float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH ) );
+
+        return pixels;
+    }
+
     static boolean isEmpty( String str )
     {
         return str == null || str.length() == 0;
index d43fd44945cd8f041bd520af0907b5b347ef8997..a1d951aaa8889ef1c4a8eb5f74b18e79e7878c4a 100644 (file)
@@ -75,6 +75,11 @@ public class HtmlDocumentFacade
         return document.createElement( "h1" );
     }
 
+    public Element createHeader2()
+    {
+        return document.createElement( "h2" );
+    }
+
     public Element createHyperlink( String internalDestination )
     {
         final Element basicLink = document.createElement( "a" );
@@ -112,6 +117,16 @@ public class HtmlDocumentFacade
         return document.createElement( "td" );
     }
 
+    public Element createTableColumn()
+    {
+        return document.createElement( "col" );
+    }
+
+    public Element createTableColumnGroup()
+    {
+        return document.createElement( "colgroup" );
+    }
+
     public Element createTableHeader()
     {
         return document.createElement( "thead" );