add initial implementation for Excel to XSL FO converter
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1162724 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fa12b281eb
commit
d6e3c74c2f
@ -0,0 +1,191 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.converter;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hwpf.converter.AbstractWordConverter;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* Common class for {@link ExcelToFoConverter} and {@link ExcelToHtmlConverter}
|
||||
*
|
||||
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
|
||||
* @see AbstractWordConverter
|
||||
*/
|
||||
@Beta
|
||||
public abstract class AbstractExcelConverter
|
||||
{
|
||||
protected static int getColumnWidth( HSSFSheet sheet, int columnIndex )
|
||||
{
|
||||
return ExcelToHtmlUtils.getColumnWidthInPx( sheet
|
||||
.getColumnWidth( columnIndex ) );
|
||||
}
|
||||
|
||||
protected final HSSFDataFormatter _formatter = new HSSFDataFormatter();
|
||||
|
||||
private boolean outputColumnHeaders = true;
|
||||
|
||||
private boolean outputHiddenColumns = false;
|
||||
|
||||
private boolean outputHiddenRows = false;
|
||||
|
||||
private boolean outputLeadingSpacesAsNonBreaking = true;
|
||||
|
||||
private boolean outputRowNumbers = true;
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
}
|
||||
|
||||
protected abstract Document getDocument();
|
||||
|
||||
/**
|
||||
* Generates name for output as row number in case
|
||||
* <tt>{@link #isOutputRowNumbers()} == true</tt>
|
||||
*/
|
||||
protected String getRowName( HSSFRow row )
|
||||
{
|
||||
return String.valueOf( row.getRowNum() + 1 );
|
||||
}
|
||||
|
||||
public boolean isOutputColumnHeaders()
|
||||
{
|
||||
return outputColumnHeaders;
|
||||
}
|
||||
|
||||
public boolean isOutputHiddenColumns()
|
||||
{
|
||||
return outputHiddenColumns;
|
||||
}
|
||||
|
||||
public boolean isOutputHiddenRows()
|
||||
{
|
||||
return outputHiddenRows;
|
||||
}
|
||||
|
||||
public boolean isOutputLeadingSpacesAsNonBreaking()
|
||||
{
|
||||
return outputLeadingSpacesAsNonBreaking;
|
||||
}
|
||||
|
||||
public boolean isOutputRowNumbers()
|
||||
{
|
||||
return outputRowNumbers;
|
||||
}
|
||||
|
||||
protected boolean isTextEmpty( HSSFCell cell )
|
||||
{
|
||||
final String value;
|
||||
switch ( cell.getCellType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
// XXX: enrich
|
||||
value = cell.getRichStringCellValue().getString();
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_FORMULA:
|
||||
switch ( cell.getCachedFormulaResultType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
HSSFRichTextString str = cell.getRichStringCellValue();
|
||||
if ( str == null || str.length() <= 0 )
|
||||
return false;
|
||||
|
||||
value = str.toString();
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
HSSFCellStyle style = cell.getCellStyle();
|
||||
if ( style == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = ( _formatter.formatRawCellContents(
|
||||
cell.getNumericCellValue(), style.getDataFormat(),
|
||||
style.getDataFormatString() ) );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BLANK:
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
value = _formatter.formatCellValue( cell );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
return ExcelToHtmlUtils.isEmpty( value );
|
||||
}
|
||||
|
||||
public void setOutputColumnHeaders( boolean outputColumnHeaders )
|
||||
{
|
||||
this.outputColumnHeaders = outputColumnHeaders;
|
||||
}
|
||||
|
||||
public void setOutputHiddenColumns( boolean outputZeroWidthColumns )
|
||||
{
|
||||
this.outputHiddenColumns = outputZeroWidthColumns;
|
||||
}
|
||||
|
||||
public void setOutputHiddenRows( boolean outputZeroHeightRows )
|
||||
{
|
||||
this.outputHiddenRows = outputZeroHeightRows;
|
||||
}
|
||||
|
||||
public void setOutputLeadingSpacesAsNonBreaking(
|
||||
boolean outputPrePostSpacesAsNonBreaking )
|
||||
{
|
||||
this.outputLeadingSpacesAsNonBreaking = outputPrePostSpacesAsNonBreaking;
|
||||
}
|
||||
|
||||
public void setOutputRowNumbers( boolean outputRowNumbers )
|
||||
{
|
||||
this.outputRowNumbers = outputRowNumbers;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.converter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hwpf.converter.AbstractWordUtils;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
|
||||
/**
|
||||
* Common class for {@link ExcelToFoUtils} and {@link ExcelToHtmlUtils}
|
||||
*
|
||||
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
|
||||
* @see AbstractWordUtils
|
||||
*/
|
||||
@Beta
|
||||
public class AbstractExcelUtils
|
||||
{
|
||||
static final String EMPTY = "";
|
||||
private static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||
private static final int UNIT_OFFSET_LENGTH = 7;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
static boolean isNotEmpty( String str )
|
||||
{
|
||||
return !isEmpty( str );
|
||||
}
|
||||
|
||||
public static HSSFWorkbook loadXls( File xlsFile ) throws IOException
|
||||
{
|
||||
final FileInputStream inputStream = new FileInputStream( xlsFile );
|
||||
try
|
||||
{
|
||||
return new HSSFWorkbook( inputStream );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtils.closeQuietly( inputStream );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,644 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.converter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.apache.poi.hpsf.SummaryInformation;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hwpf.converter.FoDocumentFacade;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
/**
|
||||
* Converts xls files (97-2007) to XSL FO.
|
||||
*
|
||||
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
|
||||
*/
|
||||
@Beta
|
||||
public class ExcelToFoConverter extends AbstractExcelConverter
|
||||
{
|
||||
private static final float CM_PER_INCH = 2.54f;
|
||||
|
||||
private static final float DPI = 72;
|
||||
|
||||
private static final POILogger logger = POILogFactory
|
||||
.getLogger( ExcelToFoConverter.class );
|
||||
|
||||
private static final float PAPER_A4_HEIGHT_INCHES = 29.4f / CM_PER_INCH;
|
||||
|
||||
private static final float PAPER_A4_WIDTH_INCHES = 21.0f / CM_PER_INCH;
|
||||
|
||||
/**
|
||||
* Java main() interface to interact with {@link ExcelToFoConverter}
|
||||
*
|
||||
* <p>
|
||||
* Usage: ExcelToHtmlConverter infile outfile
|
||||
* </p>
|
||||
* Where infile is an input .xls file ( Word 97-2007) which will be rendered
|
||||
* as XSL FO into outfile
|
||||
*/
|
||||
public static void main( String[] args )
|
||||
{
|
||||
if ( args.length < 2 )
|
||||
{
|
||||
System.err
|
||||
.println( "Usage: ExcelToFoConverter <inputFile.xls> <saveTo.xml>" );
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println( "Converting " + args[0] );
|
||||
System.out.println( "Saving output to " + args[1] );
|
||||
try
|
||||
{
|
||||
Document doc = ExcelToHtmlConverter.process( new File( args[0] ) );
|
||||
|
||||
FileWriter out = new FileWriter( args[1] );
|
||||
DOMSource domSource = new DOMSource( doc );
|
||||
StreamResult streamResult = new StreamResult( out );
|
||||
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer serializer = tf.newTransformer();
|
||||
// TODO set encoding from a command argument
|
||||
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
|
||||
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
|
||||
serializer.setOutputProperty( OutputKeys.METHOD, "xml" );
|
||||
serializer.transform( domSource, streamResult );
|
||||
out.close();
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Excel file (97-2007) into XSL FO file.
|
||||
*
|
||||
* @param xlsFile
|
||||
* file to process
|
||||
* @return DOM representation of result XSL FO
|
||||
*/
|
||||
public static Document process( File xlsFile ) throws Exception
|
||||
{
|
||||
final HSSFWorkbook workbook = ExcelToFoUtils.loadXls( xlsFile );
|
||||
ExcelToFoConverter excelToHtmlConverter = new ExcelToFoConverter(
|
||||
DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
.newDocument() );
|
||||
excelToHtmlConverter.processWorkbook( workbook );
|
||||
return excelToHtmlConverter.getDocument();
|
||||
}
|
||||
|
||||
private final FoDocumentFacade foDocumentFacade;
|
||||
|
||||
public ExcelToFoConverter( Document document )
|
||||
{
|
||||
this.foDocumentFacade = new FoDocumentFacade( document );
|
||||
}
|
||||
|
||||
protected String createPageMaster( HSSFSheet sheet, int maxSheetColumns,
|
||||
String pageMasterName )
|
||||
{
|
||||
final float paperHeightIn;
|
||||
final float paperWidthIn;
|
||||
{
|
||||
float requiredWidthIn = ExcelToFoUtils
|
||||
.getColumnWidthInPx( getSheetWidth( sheet, maxSheetColumns ) )
|
||||
/ DPI + 2;
|
||||
|
||||
if ( requiredWidthIn < PAPER_A4_WIDTH_INCHES )
|
||||
{
|
||||
// portrait orientation
|
||||
paperWidthIn = PAPER_A4_WIDTH_INCHES;
|
||||
paperHeightIn = PAPER_A4_HEIGHT_INCHES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// landscape orientation
|
||||
paperWidthIn = requiredWidthIn;
|
||||
paperHeightIn = paperWidthIn
|
||||
* ( PAPER_A4_WIDTH_INCHES / PAPER_A4_HEIGHT_INCHES );
|
||||
}
|
||||
}
|
||||
|
||||
final float leftMargin = 1;
|
||||
final float rightMargin = 1;
|
||||
final float topMargin = 1;
|
||||
final float bottomMargin = 1;
|
||||
|
||||
Element pageMaster = foDocumentFacade
|
||||
.addSimplePageMaster( pageMasterName );
|
||||
pageMaster.setAttribute( "page-height", paperHeightIn + "in" );
|
||||
pageMaster.setAttribute( "page-width", paperWidthIn + "in" );
|
||||
|
||||
Element regionBody = foDocumentFacade.addRegionBody( pageMaster );
|
||||
regionBody.setAttribute( "margin", topMargin + "in " + rightMargin
|
||||
+ "in " + bottomMargin + "in " + leftMargin + "in" );
|
||||
|
||||
return pageMasterName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Document getDocument()
|
||||
{
|
||||
return foDocumentFacade.getDocument();
|
||||
}
|
||||
|
||||
protected int getSheetWidth( HSSFSheet sheet, int maxSheetColumns )
|
||||
{
|
||||
int width = 0;
|
||||
if ( isOutputRowNumbers() )
|
||||
{
|
||||
width += sheet.getDefaultColumnWidth();
|
||||
}
|
||||
|
||||
for ( int columnIndex = 0; columnIndex < maxSheetColumns; columnIndex++ )
|
||||
{
|
||||
if ( !isOutputHiddenColumns() && sheet.isColumnHidden( columnIndex ) )
|
||||
continue;
|
||||
width += sheet.getColumnWidth( columnIndex );
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
protected boolean processCell( HSSFCell cell, Element tableCellElement,
|
||||
int normalWidthPx, int maxSpannedWidthPx, float normalHeightPt )
|
||||
{
|
||||
final HSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
|
||||
String value;
|
||||
switch ( cell.getCellType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
// XXX: enrich
|
||||
value = cell.getRichStringCellValue().getString();
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_FORMULA:
|
||||
switch ( cell.getCachedFormulaResultType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
HSSFRichTextString str = cell.getRichStringCellValue();
|
||||
if ( str != null && str.length() > 0 )
|
||||
{
|
||||
value = ( str.toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
}
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
HSSFCellStyle style = cellStyle;
|
||||
if ( style == null )
|
||||
{
|
||||
value = String.valueOf( cell.getNumericCellValue() );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ( _formatter.formatRawCellContents(
|
||||
cell.getNumericCellValue(), style.getDataFormat(),
|
||||
style.getDataFormatString() ) );
|
||||
}
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
logger.log(
|
||||
POILogger.WARN,
|
||||
"Unexpected cell cachedFormulaResultType ("
|
||||
+ cell.getCachedFormulaResultType() + ")" );
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BLANK:
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
value = _formatter.formatCellValue( cell );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
logger.log( POILogger.WARN,
|
||||
"Unexpected cell type (" + cell.getCellType() + ")" );
|
||||
return true;
|
||||
}
|
||||
|
||||
final boolean noText = ExcelToHtmlUtils.isEmpty( value );
|
||||
// final boolean wrapInDivs = !noText && isUseDivsToSpan()
|
||||
// && !cellStyle.getWrapText();
|
||||
|
||||
final short cellStyleIndex = cellStyle.getIndex();
|
||||
if ( cellStyleIndex != 0 )
|
||||
{
|
||||
// HSSFWorkbook workbook = cell.getRow().getSheet().getWorkbook();
|
||||
// String mainCssClass = getStyleClassName( workbook, cellStyle );
|
||||
// if ( wrapInDivs )
|
||||
// {
|
||||
// tableCellElement.setAttribute( "class", mainCssClass + " "
|
||||
// + cssClassContainerCell );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tableCellElement.setAttribute( "class", mainCssClass );
|
||||
// }
|
||||
|
||||
if ( noText )
|
||||
{
|
||||
/*
|
||||
* if cell style is defined (like borders, etc.) but cell text
|
||||
* is empty, add " " to output, so browser won't collapse
|
||||
* and ignore cell
|
||||
*/
|
||||
value = "\u00A0";
|
||||
}
|
||||
}
|
||||
|
||||
if ( isOutputLeadingSpacesAsNonBreaking() && value.startsWith( " " ) )
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for ( int c = 0; c < value.length(); c++ )
|
||||
{
|
||||
if ( value.charAt( c ) != ' ' )
|
||||
break;
|
||||
builder.append( '\u00a0' );
|
||||
}
|
||||
|
||||
if ( value.length() != builder.length() )
|
||||
builder.append( value.substring( builder.length() ) );
|
||||
|
||||
value = builder.toString();
|
||||
}
|
||||
|
||||
Text text = foDocumentFacade.createText( value );
|
||||
|
||||
// if ( wrapInDivs )
|
||||
// {
|
||||
// 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 );
|
||||
// innerDivStyle.append( "px;" );
|
||||
// if ( maxSpannedWidthPx != Integer.MAX_VALUE )
|
||||
// {
|
||||
// innerDivStyle.append( "max-width:" );
|
||||
// innerDivStyle.append( maxSpannedWidthPx );
|
||||
// innerDivStyle.append( "px;" );
|
||||
// }
|
||||
// innerDivStyle.append( "overflow:hidden;max-height:" );
|
||||
// innerDivStyle.append( normalHeightPt );
|
||||
// innerDivStyle.append( "pt;white-space:nowrap;" );
|
||||
// ExcelToHtmlUtils.appendAlign( innerDivStyle,
|
||||
// cellStyle.getAlignment() );
|
||||
// htmlDocumentFacade.addStyleClass( outerDiv, "d",
|
||||
// innerDivStyle.toString() );
|
||||
//
|
||||
// innerDiv.appendChild( text );
|
||||
// outerDiv.appendChild( innerDiv );
|
||||
// tableCellElement.appendChild( outerDiv );
|
||||
// }
|
||||
// else
|
||||
{
|
||||
tableCellElement.appendChild( text );
|
||||
}
|
||||
|
||||
return ExcelToHtmlUtils.isEmpty( value ) && cellStyleIndex == 0;
|
||||
}
|
||||
|
||||
protected void processColumnHeaders( HSSFSheet sheet, int maxSheetColumns,
|
||||
Element table )
|
||||
{
|
||||
Element tableHeader = foDocumentFacade.createTableHeader();
|
||||
Element row = foDocumentFacade.createTableRow();
|
||||
|
||||
if ( isOutputRowNumbers() )
|
||||
{
|
||||
// empty cell at left-top corner
|
||||
row.appendChild( foDocumentFacade.createTableCell() );
|
||||
}
|
||||
|
||||
for ( int c = 0; c < maxSheetColumns; c++ )
|
||||
{
|
||||
if ( !isOutputHiddenColumns() && sheet.isColumnHidden( c ) )
|
||||
continue;
|
||||
|
||||
Element cell = foDocumentFacade.createTableCell();
|
||||
String text = getColumnName( c );
|
||||
cell.appendChild( foDocumentFacade.createText( text ) );
|
||||
row.appendChild( cell );
|
||||
}
|
||||
|
||||
tableHeader.appendChild( row );
|
||||
table.appendChild( tableHeader );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
if ( isOutputRowNumbers() )
|
||||
{
|
||||
table.appendChild( foDocumentFacade.createTableColumn() );
|
||||
}
|
||||
|
||||
for ( int c = 0; c < maxSheetColumns; c++ )
|
||||
{
|
||||
if ( !isOutputHiddenColumns() && sheet.isColumnHidden( c ) )
|
||||
continue;
|
||||
|
||||
Element col = foDocumentFacade.createTableColumn();
|
||||
col.setAttribute( "column-width",
|
||||
String.valueOf( getColumnWidth( sheet, c ) / DPI ) + "in" );
|
||||
table.appendChild( col );
|
||||
}
|
||||
}
|
||||
|
||||
protected void processDocumentInformation(
|
||||
SummaryInformation summaryInformation )
|
||||
{
|
||||
if ( ExcelToFoUtils.isNotEmpty( summaryInformation.getTitle() ) )
|
||||
foDocumentFacade.setTitle( summaryInformation.getTitle() );
|
||||
|
||||
if ( ExcelToFoUtils.isNotEmpty( summaryInformation.getAuthor() ) )
|
||||
foDocumentFacade.setCreator( summaryInformation.getAuthor() );
|
||||
|
||||
if ( ExcelToFoUtils.isNotEmpty( summaryInformation.getKeywords() ) )
|
||||
foDocumentFacade.setKeywords( summaryInformation.getKeywords() );
|
||||
|
||||
if ( ExcelToFoUtils.isNotEmpty( summaryInformation.getComments() ) )
|
||||
foDocumentFacade.setDescription( summaryInformation.getComments() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum 1-base index of column that were rendered, zero if none
|
||||
*/
|
||||
protected int processRow( CellRangeAddress[][] mergedRanges, HSSFRow row,
|
||||
Element tableRowElement )
|
||||
{
|
||||
final HSSFSheet sheet = row.getSheet();
|
||||
final short maxColIx = row.getLastCellNum();
|
||||
if ( maxColIx <= 0 )
|
||||
return 0;
|
||||
|
||||
final List<Element> emptyCells = new ArrayList<Element>( maxColIx );
|
||||
|
||||
if ( isOutputRowNumbers() )
|
||||
{
|
||||
Element tableRowNumberCellElement = foDocumentFacade
|
||||
.createTableCell();
|
||||
processRowNumber( row, tableRowNumberCellElement );
|
||||
emptyCells.add( tableRowNumberCellElement );
|
||||
}
|
||||
|
||||
int maxRenderedColumn = 0;
|
||||
for ( int colIx = 0; colIx < maxColIx; colIx++ )
|
||||
{
|
||||
if ( !isOutputHiddenColumns() && sheet.isColumnHidden( colIx ) )
|
||||
continue;
|
||||
|
||||
CellRangeAddress range = ExcelToHtmlUtils.getMergedRange(
|
||||
mergedRanges, row.getRowNum(), colIx );
|
||||
|
||||
if ( range != null
|
||||
&& ( range.getFirstColumn() != colIx || range.getFirstRow() != row
|
||||
.getRowNum() ) )
|
||||
continue;
|
||||
|
||||
HSSFCell cell = row.getCell( colIx );
|
||||
|
||||
int divWidthPx = 0;
|
||||
// if ( isUseDivsToSpan() )
|
||||
// {
|
||||
// divWidthPx = getColumnWidth( sheet, colIx );
|
||||
//
|
||||
// boolean hasBreaks = false;
|
||||
// for ( int nextColumnIndex = colIx + 1; nextColumnIndex <
|
||||
// maxColIx; nextColumnIndex++ )
|
||||
// {
|
||||
// if ( !isOutputHiddenColumns()
|
||||
// && sheet.isColumnHidden( nextColumnIndex ) )
|
||||
// continue;
|
||||
//
|
||||
// if ( row.getCell( nextColumnIndex ) != null
|
||||
// && !isTextEmpty( row.getCell( nextColumnIndex ) ) )
|
||||
// {
|
||||
// hasBreaks = true;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// divWidthPx += getColumnWidth( sheet, nextColumnIndex );
|
||||
// }
|
||||
//
|
||||
// if ( !hasBreaks )
|
||||
// divWidthPx = Integer.MAX_VALUE;
|
||||
// }
|
||||
|
||||
Element tableCellElement = foDocumentFacade.createTableCell();
|
||||
|
||||
if ( range != null )
|
||||
{
|
||||
if ( range.getFirstColumn() != range.getLastColumn() )
|
||||
tableCellElement.setAttribute(
|
||||
"number-columns-spanned",
|
||||
String.valueOf( range.getLastColumn()
|
||||
- range.getFirstColumn() + 1 ) );
|
||||
if ( range.getFirstRow() != range.getLastRow() )
|
||||
tableCellElement.setAttribute(
|
||||
"number-rows-spanned",
|
||||
String.valueOf( range.getLastRow()
|
||||
- range.getFirstRow() + 1 ) );
|
||||
}
|
||||
|
||||
boolean emptyCell;
|
||||
if ( cell != null )
|
||||
{
|
||||
emptyCell = processCell( cell, tableCellElement,
|
||||
getColumnWidth( sheet, colIx ), divWidthPx,
|
||||
row.getHeight() / 20f );
|
||||
}
|
||||
else
|
||||
{
|
||||
emptyCell = true;
|
||||
}
|
||||
|
||||
if ( emptyCell )
|
||||
{
|
||||
emptyCells.add( tableCellElement );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( Element emptyCellElement : emptyCells )
|
||||
{
|
||||
tableRowElement.appendChild( emptyCellElement );
|
||||
}
|
||||
emptyCells.clear();
|
||||
|
||||
tableRowElement.appendChild( tableCellElement );
|
||||
maxRenderedColumn = colIx;
|
||||
}
|
||||
}
|
||||
|
||||
return maxRenderedColumn + 1;
|
||||
}
|
||||
|
||||
protected void processRowNumber( HSSFRow row,
|
||||
Element tableRowNumberCellElement )
|
||||
{
|
||||
Text text = foDocumentFacade.createText( getRowName( row ) );
|
||||
tableRowNumberCellElement.appendChild( text );
|
||||
}
|
||||
|
||||
protected int processSheet( HSSFSheet sheet, Element flow )
|
||||
{
|
||||
final int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
|
||||
if ( physicalNumberOfRows <= 0 )
|
||||
return 0;
|
||||
|
||||
processSheetName( sheet, flow );
|
||||
|
||||
Element table = foDocumentFacade.createTable();
|
||||
Element tableBody = foDocumentFacade.createTableBody();
|
||||
|
||||
final CellRangeAddress[][] mergedRanges = ExcelToHtmlUtils
|
||||
.buildMergedRangesMap( sheet );
|
||||
|
||||
final List<Element> emptyRowElements = new ArrayList<Element>(
|
||||
physicalNumberOfRows );
|
||||
int maxSheetColumns = 1;
|
||||
for ( int r = 0; r < physicalNumberOfRows; r++ )
|
||||
{
|
||||
HSSFRow row = sheet.getRow( r );
|
||||
|
||||
if ( row == null )
|
||||
continue;
|
||||
|
||||
if ( !isOutputHiddenRows() && row.getZeroHeight() )
|
||||
continue;
|
||||
|
||||
Element tableRowElement = foDocumentFacade.createTableRow();
|
||||
tableRowElement.setAttribute( "height", row.getHeight() / 20f
|
||||
+ "pt" );
|
||||
|
||||
int maxRowColumnNumber = processRow( mergedRanges, row,
|
||||
tableRowElement );
|
||||
|
||||
if ( maxRowColumnNumber == 0 )
|
||||
{
|
||||
emptyRowElements.add( tableRowElement );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !emptyRowElements.isEmpty() )
|
||||
{
|
||||
for ( Element emptyRowElement : emptyRowElements )
|
||||
{
|
||||
tableBody.appendChild( emptyRowElement );
|
||||
}
|
||||
emptyRowElements.clear();
|
||||
}
|
||||
|
||||
tableBody.appendChild( tableRowElement );
|
||||
}
|
||||
maxSheetColumns = Math.max( maxSheetColumns, maxRowColumnNumber );
|
||||
}
|
||||
|
||||
processColumnWidths( sheet, maxSheetColumns, table );
|
||||
|
||||
if ( isOutputColumnHeaders() )
|
||||
{
|
||||
processColumnHeaders( sheet, maxSheetColumns, table );
|
||||
}
|
||||
|
||||
table.appendChild( tableBody );
|
||||
flow.appendChild( table );
|
||||
|
||||
return maxSheetColumns;
|
||||
}
|
||||
|
||||
protected void processSheetName( HSSFSheet sheet, Element flow )
|
||||
{
|
||||
Element titleBlock = foDocumentFacade.createBlock();
|
||||
Element titleInline = foDocumentFacade.createInline();
|
||||
titleInline.appendChild( foDocumentFacade.createText( sheet
|
||||
.getSheetName() ) );
|
||||
titleBlock.appendChild( titleInline );
|
||||
flow.appendChild( titleBlock );
|
||||
}
|
||||
|
||||
public void processWorkbook( HSSFWorkbook workbook )
|
||||
{
|
||||
final SummaryInformation summaryInformation = workbook
|
||||
.getSummaryInformation();
|
||||
if ( summaryInformation != null )
|
||||
{
|
||||
processDocumentInformation( summaryInformation );
|
||||
}
|
||||
|
||||
for ( int s = 0; s < workbook.getNumberOfSheets(); s++ )
|
||||
{
|
||||
String pageMasterName = "sheet-" + s;
|
||||
|
||||
Element pageSequence = foDocumentFacade
|
||||
.addPageSequence( pageMasterName );
|
||||
Element flow = foDocumentFacade.addFlowToPageSequence(
|
||||
pageSequence, "xsl-region-body" );
|
||||
|
||||
HSSFSheet sheet = workbook.getSheetAt( s );
|
||||
int maxSheetColumns = processSheet( sheet, flow );
|
||||
|
||||
if ( maxSheetColumns != 0 )
|
||||
createPageMaster( sheet, maxSheetColumns, pageMasterName );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.converter;
|
||||
|
||||
import org.apache.poi.util.Beta;
|
||||
|
||||
@Beta
|
||||
public class ExcelToFoUtils extends AbstractExcelUtils
|
||||
{
|
||||
|
||||
}
|
@ -33,7 +33,6 @@ import javax.xml.transform.stream.StreamResult;
|
||||
import org.apache.poi.hpsf.SummaryInformation;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFont;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
@ -43,6 +42,7 @@ import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.hwpf.converter.HtmlDocumentFacade;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.w3c.dom.Document;
|
||||
@ -54,18 +54,13 @@ import org.w3c.dom.Text;
|
||||
*
|
||||
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
|
||||
*/
|
||||
public class ExcelToHtmlConverter
|
||||
@Beta
|
||||
public class ExcelToHtmlConverter extends AbstractExcelConverter
|
||||
{
|
||||
|
||||
private static final POILogger logger = POILogFactory
|
||||
.getLogger( ExcelToHtmlConverter.class );
|
||||
|
||||
protected static int getColumnWidth( HSSFSheet sheet, int columnIndex )
|
||||
{
|
||||
return ExcelToHtmlUtils.getColumnWidthInPx( sheet
|
||||
.getColumnWidth( columnIndex ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Java main() interface to interact with {@link ExcelToHtmlConverter}
|
||||
*
|
||||
@ -80,7 +75,7 @@ public class ExcelToHtmlConverter
|
||||
if ( args.length < 2 )
|
||||
{
|
||||
System.err
|
||||
.println( "Usage: ExcelToHtmlConverter <inputFile.doc> <saveTo.html>" );
|
||||
.println( "Usage: ExcelToHtmlConverter <inputFile.xls> <saveTo.html>" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,7 +93,7 @@ public class ExcelToHtmlConverter
|
||||
Transformer serializer = tf.newTransformer();
|
||||
// TODO set encoding from a command argument
|
||||
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
|
||||
serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
|
||||
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
|
||||
serializer.setOutputProperty( OutputKeys.METHOD, "html" );
|
||||
serializer.transform( domSource, streamResult );
|
||||
out.close();
|
||||
@ -126,8 +121,6 @@ public class ExcelToHtmlConverter
|
||||
return excelToHtmlConverter.getDocument();
|
||||
}
|
||||
|
||||
private final HSSFDataFormatter _formatter = new HSSFDataFormatter();
|
||||
|
||||
private String cssClassContainerCell = null;
|
||||
|
||||
private String cssClassContainerDiv = null;
|
||||
@ -138,16 +131,6 @@ public class ExcelToHtmlConverter
|
||||
|
||||
private final HtmlDocumentFacade htmlDocumentFacade;
|
||||
|
||||
private boolean outputColumnHeaders = true;
|
||||
|
||||
private boolean outputHiddenColumns = false;
|
||||
|
||||
private boolean outputHiddenRows = false;
|
||||
|
||||
private boolean outputLeadingSpacesAsNonBreaking = true;
|
||||
|
||||
private boolean outputRowNumbers = true;
|
||||
|
||||
private boolean useDivsToSpan = false;
|
||||
|
||||
public ExcelToHtmlConverter( Document doc )
|
||||
@ -251,32 +234,11 @@ 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 );
|
||||
}
|
||||
|
||||
protected String getStyleClassName( HSSFWorkbook workbook,
|
||||
HSSFCellStyle cellStyle )
|
||||
{
|
||||
@ -293,91 +255,6 @@ public class ExcelToHtmlConverter
|
||||
return cssClass;
|
||||
}
|
||||
|
||||
public boolean isOutputColumnHeaders()
|
||||
{
|
||||
return outputColumnHeaders;
|
||||
}
|
||||
|
||||
public boolean isOutputHiddenColumns()
|
||||
{
|
||||
return outputHiddenColumns;
|
||||
}
|
||||
|
||||
public boolean isOutputHiddenRows()
|
||||
{
|
||||
return outputHiddenRows;
|
||||
}
|
||||
|
||||
public boolean isOutputLeadingSpacesAsNonBreaking()
|
||||
{
|
||||
return outputLeadingSpacesAsNonBreaking;
|
||||
}
|
||||
|
||||
public boolean isOutputRowNumbers()
|
||||
{
|
||||
return outputRowNumbers;
|
||||
}
|
||||
|
||||
protected boolean isTextEmpty( HSSFCell cell )
|
||||
{
|
||||
final String value;
|
||||
switch ( cell.getCellType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
// XXX: enrich
|
||||
value = cell.getRichStringCellValue().getString();
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_FORMULA:
|
||||
switch ( cell.getCachedFormulaResultType() )
|
||||
{
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
HSSFRichTextString str = cell.getRichStringCellValue();
|
||||
if ( str == null || str.length() <= 0 )
|
||||
return false;
|
||||
|
||||
value = str.toString();
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
HSSFCellStyle style = cell.getCellStyle();
|
||||
if ( style == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = ( _formatter.formatRawCellContents(
|
||||
cell.getNumericCellValue(), style.getDataFormat(),
|
||||
style.getDataFormatString() ) );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BLANK:
|
||||
value = ExcelToHtmlUtils.EMPTY;
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
value = _formatter.formatCellValue( cell );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
value = String.valueOf( cell.getBooleanCellValue() );
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_ERROR:
|
||||
value = ErrorEval.getText( cell.getErrorCellValue() );
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
return ExcelToHtmlUtils.isEmpty( value );
|
||||
}
|
||||
|
||||
public boolean isUseDivsToSpan()
|
||||
{
|
||||
return useDivsToSpan;
|
||||
@ -831,32 +708,6 @@ public class ExcelToHtmlConverter
|
||||
htmlDocumentFacade.updateStylesheet();
|
||||
}
|
||||
|
||||
public void setOutputColumnHeaders( boolean outputColumnHeaders )
|
||||
{
|
||||
this.outputColumnHeaders = outputColumnHeaders;
|
||||
}
|
||||
|
||||
public void setOutputHiddenColumns( boolean outputZeroWidthColumns )
|
||||
{
|
||||
this.outputHiddenColumns = outputZeroWidthColumns;
|
||||
}
|
||||
|
||||
public void setOutputHiddenRows( boolean outputZeroHeightRows )
|
||||
{
|
||||
this.outputHiddenRows = outputZeroHeightRows;
|
||||
}
|
||||
|
||||
public void setOutputLeadingSpacesAsNonBreaking(
|
||||
boolean outputPrePostSpacesAsNonBreaking )
|
||||
{
|
||||
this.outputLeadingSpacesAsNonBreaking = outputPrePostSpacesAsNonBreaking;
|
||||
}
|
||||
|
||||
public void setOutputRowNumbers( boolean outputRowNumbers )
|
||||
{
|
||||
this.outputRowNumbers = outputRowNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows converter to wrap content into two additional DIVs with tricky
|
||||
* styles, so it will wrap across empty cells (like in Excel).
|
||||
|
@ -16,25 +16,17 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.converter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.Beta;
|
||||
|
||||
public class ExcelToHtmlUtils
|
||||
@Beta
|
||||
public class ExcelToHtmlUtils extends AbstractExcelUtils
|
||||
{
|
||||
static final String EMPTY = "";
|
||||
|
||||
private static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||
private static final int UNIT_OFFSET_LENGTH = 7;
|
||||
|
||||
public static void appendAlign( StringBuilder style, short alignment )
|
||||
{
|
||||
switch ( alignment )
|
||||
@ -196,23 +188,6 @@ public class ExcelToHtmlUtils
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mergedRanges
|
||||
* map of sheet merged ranges built with
|
||||
@ -232,27 +207,4 @@ public class ExcelToHtmlUtils
|
||||
return cellRangeAddress;
|
||||
}
|
||||
|
||||
static boolean isEmpty( String str )
|
||||
{
|
||||
return str == null || str.length() == 0;
|
||||
}
|
||||
|
||||
static boolean isNotEmpty( String str )
|
||||
{
|
||||
return !isEmpty( str );
|
||||
}
|
||||
|
||||
public static HSSFWorkbook loadXls( File xlsFile ) throws IOException
|
||||
{
|
||||
final FileInputStream inputStream = new FileInputStream( xlsFile );
|
||||
try
|
||||
{
|
||||
return new HSSFWorkbook( inputStream );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtils.closeQuietly( inputStream );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class FoDocumentFacade
|
||||
return simplePageMaster;
|
||||
}
|
||||
|
||||
protected Element createBasicLinkExternal( String externalDestination )
|
||||
public Element createBasicLinkExternal( String externalDestination )
|
||||
{
|
||||
final Element basicLink = document.createElementNS( NS_XSLFO,
|
||||
"fo:basic-link" );
|
||||
@ -184,32 +184,37 @@ public class FoDocumentFacade
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Element createTable()
|
||||
public Element createTable()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table" );
|
||||
}
|
||||
|
||||
protected Element createTableBody()
|
||||
public Element createTableBody()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table-body" );
|
||||
}
|
||||
|
||||
protected Element createTableCell()
|
||||
public Element createTableCell()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table-cell" );
|
||||
}
|
||||
|
||||
protected Element createTableHeader()
|
||||
public Element createTableColumn()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table-column" );
|
||||
}
|
||||
|
||||
public Element createTableHeader()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table-header" );
|
||||
}
|
||||
|
||||
protected Element createTableRow()
|
||||
public Element createTableRow()
|
||||
{
|
||||
return document.createElementNS( NS_XSLFO, "fo:table-row" );
|
||||
}
|
||||
|
||||
protected Text createText( String data )
|
||||
public Text createText( String data )
|
||||
{
|
||||
return document.createTextNode( data );
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ import junit.framework.TestSuite;
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
public class TestExcelToHtmlConverterSuite
|
||||
public class TestExcelConverterSuite
|
||||
{
|
||||
/**
|
||||
* YK: a quick hack to exclude failing documents from the suite.
|
||||
@ -48,7 +48,7 @@ public class TestExcelToHtmlConverterSuite
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite(
|
||||
TestExcelToHtmlConverterSuite.class.getName() );
|
||||
TestExcelConverterSuite.class.getName() );
|
||||
|
||||
File directory = POIDataSamples.getSpreadSheetInstance().getFile(
|
||||
"../spreadsheet" );
|
||||
@ -61,20 +61,26 @@ public class TestExcelToHtmlConverterSuite
|
||||
} ) )
|
||||
{
|
||||
final String name = child.getName();
|
||||
suite.addTest( new TestCase( name + " [FO]" )
|
||||
{
|
||||
public void runTest() throws Exception
|
||||
{
|
||||
testFo( child );
|
||||
}
|
||||
} );
|
||||
suite.addTest( new TestCase( name + " [HTML]" )
|
||||
{
|
||||
public void runTest() throws Exception
|
||||
{
|
||||
test( child, true );
|
||||
testHtml( child );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
protected static void test( File child, boolean html ) throws Exception
|
||||
protected static void testFo( File child ) throws Exception
|
||||
{
|
||||
HSSFWorkbook workbook;
|
||||
try
|
||||
@ -98,13 +104,39 @@ public class TestExcelToHtmlConverterSuite
|
||||
.newTransformer();
|
||||
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
|
||||
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
|
||||
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
|
||||
transformer.transform(
|
||||
new DOMSource( excelToHtmlConverter.getDocument() ),
|
||||
new StreamResult( stringWriter ) );
|
||||
}
|
||||
|
||||
if ( html )
|
||||
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
||||
protected static void testHtml( File child ) throws Exception
|
||||
{
|
||||
HSSFWorkbook workbook;
|
||||
try
|
||||
{
|
||||
workbook = ExcelToHtmlUtils.loadXls( child );
|
||||
}
|
||||
catch ( Exception exc )
|
||||
{
|
||||
// unable to parse file -- not WordToFoConverter fault
|
||||
return;
|
||||
}
|
||||
|
||||
// no exceptions
|
||||
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
|
||||
DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
.newDocument() );
|
||||
excelToHtmlConverter.processWorkbook( workbook );
|
||||
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
|
||||
Transformer transformer = TransformerFactory.newInstance()
|
||||
.newTransformer();
|
||||
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
|
||||
transformer.setOutputProperty( OutputKeys.INDENT, "no" );
|
||||
transformer.setOutputProperty( OutputKeys.METHOD, "html" );
|
||||
transformer.transform(
|
||||
new DOMSource( excelToHtmlConverter.getDocument() ),
|
||||
new StreamResult( stringWriter ) );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user