]> source.dussan.org Git - poi.git/commitdiff
compact result HTML in Excel-to-HTML converter
authorSergey Vladimirov <sergey@apache.org>
Mon, 18 Jul 2011 20:27:35 +0000 (20:27 +0000)
committerSergey Vladimirov <sergey@apache.org>
Mon, 18 Jul 2011 20:27:35 +0000 (20:27 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148040 13f79535-47bb-0310-9956-ffa450edef68

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

index d3aadf34cbce3e7864c3974f75675ed742c962d6..50f2a38c59c1051c1890db462568824a8538ed14 100644 (file)
@@ -127,7 +127,11 @@ public class ExcelToHtmlConverter
 
     private final HSSFDataFormatter _formatter = new HSSFDataFormatter();
 
-    private Map<String, String> cssStyleToClass = new LinkedHashMap<String, String>();
+    private String cssClassContainerCell = null;
+
+    private String cssClassContainerDiv = null;
+
+    private final String cssClassTable;
 
     private Map<Short, String> excelStyleToClass = new LinkedHashMap<Short, String>();
 
@@ -143,17 +147,13 @@ public class ExcelToHtmlConverter
 
     private boolean outputRowNumbers = true;
 
-    private final Element stylesElement;
-
     private boolean useDivsToSpan = false;
 
     public ExcelToHtmlConverter( Document doc )
     {
         htmlDocumentFacade = new HtmlDocumentFacade( doc );
-
-        stylesElement = doc.createElement( "style" );
-        stylesElement.setAttribute( "type", "text/css" );
-        htmlDocumentFacade.getHead().appendChild( stylesElement );
+        cssClassTable = htmlDocumentFacade.getOrCreateCssClass( "table", "t",
+                "border-collapse:collapse;border-spacing:0;" );
     }
 
     protected String buildStyle( HSSFWorkbook workbook, HSSFCellStyle cellStyle )
@@ -279,25 +279,17 @@ public class ExcelToHtmlConverter
     protected String getStyleClassName( HSSFWorkbook workbook,
             HSSFCellStyle cellStyle )
     {
-        String knownClass = excelStyleToClass.get( Short.valueOf( cellStyle
-                .getIndex() ) );
-        if ( knownClass != null )
-            return knownClass;
+        final Short cellStyleKey = Short.valueOf( cellStyle.getIndex() );
 
-        String cssStyle = buildStyle( workbook, cellStyle );
-        knownClass = cssStyleToClass.get( cssStyle );
+        String knownClass = excelStyleToClass.get( cellStyleKey );
         if ( knownClass != null )
-        {
-            excelStyleToClass.put( Short.valueOf( cellStyle.getIndex() ),
-                    knownClass );
             return knownClass;
-        }
 
-        knownClass = "c" + cellStyle.getIndex();
-        cssStyleToClass.put( cssStyle, knownClass );
-        excelStyleToClass.put( Short.valueOf( cellStyle.getIndex() ),
-                knownClass );
-        return knownClass;
+        String cssStyle = buildStyle( workbook, cellStyle );
+        String cssClass = htmlDocumentFacade.getOrCreateCssClass( "td", "c",
+                cssStyle );
+        excelStyleToClass.put( cellStyleKey, cssClass );
+        return cssClass;
     }
 
     public boolean isOutputColumnHeaders()
@@ -467,8 +459,17 @@ public class ExcelToHtmlConverter
         final short cellStyleIndex = cellStyle.getIndex();
         if ( cellStyleIndex != 0 )
         {
-            tableCellElement.setAttribute( "class",
-                    getStyleClassName( workbook, cellStyle ) );
+            String mainCssClass = getStyleClassName( workbook, cellStyle );
+            if ( !noText && isUseDivsToSpan() )
+            {
+                tableCellElement.setAttribute( "class", mainCssClass + " "
+                        + cssClassContainerCell );
+            }
+            else
+            {
+                tableCellElement.setAttribute( "class", mainCssClass );
+            }
+
             if ( noText )
             {
                 /*
@@ -500,14 +501,10 @@ public class ExcelToHtmlConverter
 
         if ( !noText && isUseDivsToSpan() )
         {
-            tableCellElement.setAttribute( "style",
-                    "padding:0;margin:0;align:left;vertical-align:top;" );
-            Element outerDiv = htmlDocumentFacade.getDocument().createElement(
-                    "div" );
-            outerDiv.setAttribute( "style", "position:relative;" );
-
-            Element innerDiv = htmlDocumentFacade.getDocument().createElement(
-                    "div" );
+            Element outerDiv = htmlDocumentFacade.createBlock();
+            outerDiv.setAttribute( "class", this.cssClassContainerDiv );
+
+            Element innerDiv = htmlDocumentFacade.createBlock();
             StringBuilder innerDivStyle = new StringBuilder();
             innerDivStyle.append( "position:absolute;min-width:" );
             innerDivStyle.append( normalWidthPx );
@@ -523,7 +520,11 @@ public class ExcelToHtmlConverter
             innerDivStyle.append( "pt;white-space:nowrap;" );
             ExcelToHtmlUtils.appendAlign( innerDivStyle,
                     cellStyle.getAlignment() );
-            innerDiv.setAttribute( "style", innerDivStyle.toString() );
+            innerDiv.setAttribute(
+                    "class",
+                    htmlDocumentFacade.getOrCreateCssClass(
+                            outerDiv.getTagName(), "d",
+                            innerDivStyle.toString() ) );
 
             innerDiv.appendChild( text );
             outerDiv.appendChild( innerDiv );
@@ -712,7 +713,7 @@ public class ExcelToHtmlConverter
             return;
 
         Element table = htmlDocumentFacade.createTable();
-        table.setAttribute( "class", "t" );
+        table.setAttribute( "class", cssClassTable );
 
         Element tableBody = htmlDocumentFacade.createTableBody();
 
@@ -730,8 +731,11 @@ public class ExcelToHtmlConverter
                 continue;
 
             Element tableRowElement = htmlDocumentFacade.createTableRow();
-            tableRowElement.setAttribute( "style",
-                    "height:" + ( row.getHeight() / 20f ) + "pt;" );
+            tableRowElement.setAttribute(
+                    "class",
+                    htmlDocumentFacade.getOrCreateCssClass(
+                            tableRowElement.getTagName(), "r", "height:"
+                                    + ( row.getHeight() / 20f ) + "pt;" ) );
 
             int maxRowColumnNumber = processRow( workbook, sheet, row,
                     tableRowElement );
@@ -784,23 +788,23 @@ public class ExcelToHtmlConverter
             processDocumentInformation( summaryInformation );
         }
 
+        if ( isUseDivsToSpan() )
+        {
+            // prepare CSS classes for later usage
+            this.cssClassContainerCell = htmlDocumentFacade
+                    .getOrCreateCssClass( "td", "c",
+                            "padding:0;margin:0;align:left;vertical-align:top;" );
+            this.cssClassContainerDiv = htmlDocumentFacade.getOrCreateCssClass(
+                    "div", "d", "position:relative;" );
+        }
+
         for ( int s = 0; s < workbook.getNumberOfSheets(); s++ )
         {
             HSSFSheet sheet = workbook.getSheetAt( s );
             processSheet( workbook, sheet );
         }
 
-        stylesElement
-                .appendChild( htmlDocumentFacade
-                        .createText( "table.t{border-collapse:collapse;border-spacing:0;}\n" ) );
-        if ( !cssStyleToClass.isEmpty() )
-        {
-            for ( Map.Entry<String, String> entry : cssStyleToClass.entrySet() )
-            {
-                stylesElement.appendChild( htmlDocumentFacade.createText( "td."
-                        + entry.getValue() + "{" + entry.getKey() + "}\n" ) );
-            }
-        }
+        htmlDocumentFacade.updateStylesheet();
     }
 
     public void setOutputColumnHeaders( boolean outputColumnHeaders )
index a1d951aaa8889ef1c4a8eb5f74b18e79e7878c4a..6cd6227a1ae237819edf7145a1a172dd2d6edd25 100644 (file)
 ==================================================================== */
 package org.apache.poi.hwpf.converter;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Text;
 
 public class HtmlDocumentFacade
 {
-
     protected final Element body;
     protected final Document document;
     protected final Element head;
     protected final Element html;
 
+    /**
+     * Map from tag name, to map linking known styles and css class names
+     */
+    private Map<String, Map<String, String>> stylesheet = new LinkedHashMap<String, Map<String, String>>();
+    private Element stylesheetElement;
+
     protected Element title;
     protected Text titleText;
 
@@ -40,11 +48,17 @@ public class HtmlDocumentFacade
 
         body = document.createElement( "body" );
         head = document.createElement( "head" );
+        stylesheetElement = document.createElement( "style" );
+        stylesheetElement.setAttribute( "type", "text/css" );
 
         html.appendChild( head );
         html.appendChild( body );
+        head.appendChild( stylesheetElement );
 
-        body.setAttribute( "style", "white-space-collapsing: preserve; " );
+        body.setAttribute(
+                "class",
+                getOrCreateCssClass( "body", "b",
+                        "white-space-collapsing: preserve; " ) );
     }
 
     public void addAuthor( String value )
@@ -70,6 +84,11 @@ public class HtmlDocumentFacade
         head.appendChild( meta );
     }
 
+    public Element createBlock()
+    {
+        return document.createElement( "div" );
+    }
+
     public Element createHeader1()
     {
         return document.createElement( "h1" );
@@ -167,6 +186,22 @@ public class HtmlDocumentFacade
         return head;
     }
 
+    public String getOrCreateCssClass( String tagName, String classNamePrefix,
+            String style )
+    {
+        if ( !stylesheet.containsKey( tagName ) )
+            stylesheet.put( tagName, new LinkedHashMap<String, String>( 1 ) );
+
+        Map<String, String> styleToClassName = stylesheet.get( tagName );
+        String knownClass = styleToClassName.get( style );
+        if ( knownClass != null )
+            return knownClass;
+
+        String newClassName = classNamePrefix + ( styleToClassName.size() + 1 );
+        styleToClassName.put( style, newClassName );
+        return newClassName;
+    }
+
     public String getTitle()
     {
         if ( title == null )
@@ -194,4 +229,24 @@ public class HtmlDocumentFacade
 
         this.titleText.setData( titleText );
     }
+
+    public void updateStylesheet()
+    {
+        StringBuilder stringBuilder = new StringBuilder();
+        for ( Map.Entry<String, Map<String, String>> byTag : stylesheet
+                .entrySet() )
+        {
+            String tagName = byTag.getKey();
+            for ( Map.Entry<String, String> byStyle : byTag.getValue()
+                    .entrySet() )
+            {
+                String style = byStyle.getKey();
+                String className = byStyle.getValue();
+
+                stringBuilder.append( tagName + "." + className + "{" + style
+                        + "}\n" );
+            }
+        }
+        stylesheetElement.setTextContent( stringBuilder.toString() );
+    }
 }