compact result HTML in Excel-to-HTML converter

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148040 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sergey Vladimirov 2011-07-18 20:27:35 +00:00
parent 8e4853b55e
commit 29e9f487d5
2 changed files with 107 additions and 48 deletions

View 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() ) );
final Short cellStyleKey = Short.valueOf( cellStyle.getIndex() );
String knownClass = excelStyleToClass.get( cellStyleKey );
if ( knownClass != null )
return knownClass;
String cssStyle = buildStyle( workbook, cellStyle );
knownClass = cssStyleToClass.get( cssStyle );
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 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 outerDiv = htmlDocumentFacade.createBlock();
outerDiv.setAttribute( "class", this.cssClassContainerDiv );
Element innerDiv = htmlDocumentFacade.getDocument().createElement(
"div" );
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 )

View File

@ -16,18 +16,26 @@
==================================================================== */
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() );
}
}