From 6e5b818c94ce598f20b44a62a2e61f9a9b04d37c Mon Sep 17 00:00:00 2001 From: Sergey Vladimirov Date: Mon, 18 Jul 2011 23:09:11 +0000 Subject: [PATCH] add support for merged cells git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148089 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/converter/ExcelToHtmlConverter.java | 88 +++++++++++++++++-- .../poi/hssf/converter/ExcelToHtmlUtils.java | 13 +++ 2 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java index 50f2a38c59..08f052cc21 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java +++ b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java @@ -19,6 +19,7 @@ package org.apache.poi.hssf.converter; import java.io.File; import java.io.FileWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -42,6 +43,7 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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.POILogFactory; import org.apache.poi.util.POILogger; import org.w3c.dom.Document; @@ -455,12 +457,15 @@ public class ExcelToHtmlConverter return true; } - boolean noText = ExcelToHtmlUtils.isEmpty( value ); + final boolean noText = ExcelToHtmlUtils.isEmpty( value ); + final boolean wrapInDivs = !noText && isUseDivsToSpan() + && !cellStyle.getWrapText(); + final short cellStyleIndex = cellStyle.getIndex(); if ( cellStyleIndex != 0 ) { String mainCssClass = getStyleClassName( workbook, cellStyle ); - if ( !noText && isUseDivsToSpan() ) + if ( wrapInDivs ) { tableCellElement.setAttribute( "class", mainCssClass + " " + cssClassContainerCell ); @@ -499,7 +504,7 @@ public class ExcelToHtmlConverter Text text = htmlDocumentFacade.createText( value ); - if ( !noText && isUseDivsToSpan() ) + if ( wrapInDivs ) { Element outerDiv = htmlDocumentFacade.createBlock(); outerDiv.setAttribute( "class", this.cssClassContainerDiv ); @@ -612,7 +617,8 @@ public class ExcelToHtmlConverter * @return maximum 1-base index of column that were rendered, zero if none */ protected int processRow( HSSFWorkbook workbook, HSSFSheet sheet, - HSSFRow row, Element tableRowElement ) + CellRangeAddress[][] mergedRanges, HSSFRow row, + Element tableRowElement ) { final short maxColIx = row.getLastCellNum(); if ( maxColIx <= 0 ) @@ -631,11 +637,19 @@ public class ExcelToHtmlConverter int maxRenderedColumn = 0; for ( int colIx = 0; colIx < maxColIx; colIx++ ) { - HSSFCell cell = row.getCell( colIx ); - if ( !isOutputHiddenColumns() && sheet.isColumnHidden( colIx ) ) continue; + CellRangeAddress range = ExcelToHtmlUtils.getCellRangeAddress( + 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() ) { @@ -664,6 +678,20 @@ public class ExcelToHtmlConverter Element tableCellElement = htmlDocumentFacade.createTableCell(); + if ( range != null ) + { + if ( range.getFirstColumn() != range.getLastColumn() ) + tableCellElement.setAttribute( + "colspan", + String.valueOf( range.getLastColumn() + - range.getFirstColumn() + 1 ) ); + if ( range.getFirstRow() != range.getLastRow() ) + tableCellElement.setAttribute( + "rowspan", + String.valueOf( range.getLastRow() + - range.getFirstRow() + 1 ) ); + } + boolean emptyCell; if ( cell != null ) { @@ -717,6 +745,50 @@ public class ExcelToHtmlConverter Element tableBody = htmlDocumentFacade.createTableBody(); + CellRangeAddress[][] mergedRanges = new CellRangeAddress[1][]; + for ( int m = 0; m < sheet.getNumMergedRegions(); m++ ) + { + final CellRangeAddress cellRangeAddress = sheet.getMergedRegion( m ); + + final int requiredHeight = cellRangeAddress.getLastRow() + 1; + if ( mergedRanges.length < requiredHeight ) + { + CellRangeAddress[][] newArray = new CellRangeAddress[requiredHeight][]; + System.arraycopy( mergedRanges, 0, newArray, 0, + mergedRanges.length ); + mergedRanges = newArray; + } + + for ( int r = cellRangeAddress.getFirstRow(); r <= cellRangeAddress + .getLastRow(); r++ ) + { + final int requiredWidth = cellRangeAddress.getLastColumn() + 1; + + CellRangeAddress[] rowMerged = mergedRanges[r]; + if ( rowMerged == null ) + { + rowMerged = new CellRangeAddress[requiredWidth]; + mergedRanges[r] = rowMerged; + } + else + { + final int rowMergedLength = rowMerged.length; + if ( rowMergedLength < requiredWidth ) + { + final CellRangeAddress[] newRow = new CellRangeAddress[requiredWidth]; + System.arraycopy( rowMerged, 0, newRow, 0, + rowMergedLength ); + + mergedRanges[r] = newRow; + rowMerged = newRow; + } + } + + Arrays.fill( rowMerged, cellRangeAddress.getFirstColumn(), + cellRangeAddress.getLastColumn() + 1, cellRangeAddress ); + } + } + final List emptyRowElements = new ArrayList( physicalNumberOfRows ); int maxSheetColumns = 1; @@ -737,8 +809,8 @@ public class ExcelToHtmlConverter tableRowElement.getTagName(), "r", "height:" + ( row.getHeight() / 20f ) + "pt;" ) ); - int maxRowColumnNumber = processRow( workbook, sheet, row, - tableRowElement ); + int maxRowColumnNumber = processRow( workbook, sheet, mergedRanges, + row, tableRowElement ); if ( maxRowColumnNumber == 0 ) { diff --git a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlUtils.java b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlUtils.java index 4be80b97f6..8a8aef70d1 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlUtils.java +++ b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlUtils.java @@ -23,6 +23,7 @@ import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFCellStyle; 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; public class ExcelToHtmlUtils @@ -110,6 +111,18 @@ public class ExcelToHtmlUtils return borderWidth; } + public static CellRangeAddress getCellRangeAddress( + CellRangeAddress[][] mergedRanges, int rowNumber, int columnNumber ) + { + CellRangeAddress[] mergedRangeRowInfo = rowNumber < mergedRanges.length ? mergedRanges[rowNumber] + : null; + CellRangeAddress cellRangeAddress = mergedRangeRowInfo != null + && columnNumber < mergedRangeRowInfo.length ? mergedRangeRowInfo[columnNumber] + : null; + + return cellRangeAddress; + } + public static String getColor( HSSFColor color ) { StringBuilder stringBuilder = new StringBuilder( 7 ); -- 2.39.5