aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/poi/ss/util
diff options
context:
space:
mode:
authorDominik Stadler <centic@apache.org>2020-03-08 11:17:34 +0000
committerDominik Stadler <centic@apache.org>2020-03-08 11:17:34 +0000
commita7d96dcb734ce2ea24e1d9670774f116c1f937d5 (patch)
treecadc6b3fd93162bd028e222fdacdf6471eac5112 /src/java/org/apache/poi/ss/util
parentd57edf14f629b44b449c04a54aa85d57cc950c10 (diff)
downloadpoi-a7d96dcb734ce2ea24e1d9670774f116c1f937d5.tar.gz
poi-a7d96dcb734ce2ea24e1d9670774f116c1f937d5.zip
Bug 58896 and 52834: Cache Sheet.getMergedRegions() as it seems to sometimes be the culprit for autosize taking a very long time.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1874973 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/poi/ss/util')
-rw-r--r--src/java/org/apache/poi/ss/util/SheetUtil.java47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/java/org/apache/poi/ss/util/SheetUtil.java b/src/java/org/apache/poi/ss/util/SheetUtil.java
index e5c2a31ba9..dcedf03a14 100644
--- a/src/java/org/apache/poi/ss/util/SheetUtil.java
+++ b/src/java/org/apache/poi/ss/util/SheetUtil.java
@@ -23,6 +23,7 @@ import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.text.AttributedString;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -118,6 +119,26 @@ public class SheetUtil {
* @return the width in pixels or -1 if cell is empty
*/
public static double getCellWidth(Cell cell, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) {
+ List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
+ return getCellWidth(cell, defaultCharWidth, formatter, useMergedCells, mergedRegions);
+ }
+
+ /**
+ * Compute width of a single cell
+ *
+ * This method receives the list of merged regions as querying it from the cell/sheet
+ * is time-consuming and thus caching the list across cells speeds up certain operations
+ * considerably.
+ *
+ * @param cell the cell whose width is to be calculated
+ * @param defaultCharWidth the width of a single character
+ * @param formatter formatter used to prepare the text to be measured
+ * @param useMergedCells whether to use merged cells
+ * @param mergedRegions The list of merged regions as received via cell.getSheet().getMergedRegions()
+ * @return the width in pixels or -1 if cell is empty
+ */
+ public static double getCellWidth(Cell cell, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells,
+ List<CellRangeAddress> mergedRegions) {
Sheet sheet = cell.getSheet();
Workbook wb = sheet.getWorkbook();
Row row = cell.getRow();
@@ -126,7 +147,7 @@ public class SheetUtil {
// FIXME: this looks very similar to getCellWithMerges below. Consider consolidating.
// We should only be checking merged regions if useMergedCells is true. Why are we doing this for-loop?
int colspan = 1;
- for (CellRangeAddress region : sheet.getMergedRegions()) {
+ for (CellRangeAddress region : mergedRegions) {
if (region.isInRange(row.getRowNum(), column)) {
if (!useMergedCells) {
// If we're not using merged cells, skip this one and move on to the next.
@@ -232,7 +253,7 @@ public class SheetUtil {
public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells) {
return getColumnWidth(sheet, column, useMergedCells, sheet.getFirstRowNum(), sheet.getLastRowNum());
}
-
+
/**
* Compute width of a column based on a subset of the rows and return the result
*
@@ -247,11 +268,12 @@ public class SheetUtil {
DataFormatter formatter = new DataFormatter();
int defaultCharWidth = getDefaultCharWidth(sheet.getWorkbook());
+ List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
double width = -1;
for (int rowIdx = firstRow; rowIdx <= lastRow; ++rowIdx) {
Row row = sheet.getRow(rowIdx);
if( row != null ) {
- double cellWidth = getColumnWidthForRow(row, column, defaultCharWidth, formatter, useMergedCells);
+ double cellWidth = getColumnWidthForRow(row, column, defaultCharWidth, formatter, useMergedCells, mergedRegions);
width = Math.max(width, cellWidth);
}
}
@@ -286,7 +308,8 @@ public class SheetUtil {
* @return the width in pixels or -1 if cell is empty
*/
private static double getColumnWidthForRow(
- Row row, int column, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) {
+ Row row, int column, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells,
+ List<CellRangeAddress> mergedRegions) {
if( row == null ) {
return -1;
}
@@ -297,16 +320,16 @@ public class SheetUtil {
return -1;
}
- return getCellWidth(cell, defaultCharWidth, formatter, useMergedCells);
+ return getCellWidth(cell, defaultCharWidth, formatter, useMergedCells, mergedRegions);
}
/**
* Check if the Fonts are installed correctly so that Java can compute the size of
- * columns.
- *
- * If a Cell uses a Font which is not available on the operating system then Java may
+ * columns.
+ *
+ * If a Cell uses a Font which is not available on the operating system then Java may
* fail to return useful Font metrics and thus lead to an auto-computed size of 0.
- *
+ *
* This method allows to check if computing the sizes for a given Font will succeed or not.
*
* @param font The Font that is used in the Cell
@@ -358,7 +381,7 @@ public class SheetUtil {
/**
* Return the cell, taking account of merged regions. Allows you to find the
* cell who's contents are shown in a given position in the sheet.
- *
+ *
* <p>If the cell at the given co-ordinates is a merged cell, this will
* return the primary (top-left) most cell of the merged region.
* <p>If the cell at the given co-ordinates is not in a merged region,
@@ -375,7 +398,7 @@ public class SheetUtil {
public static Cell getCellWithMerges(Sheet sheet, int rowIx, int colIx) {
final Cell c = getCell(sheet, rowIx, colIx);
if (c != null) return c;
-
+
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.isInRange(rowIx, colIx)) {
// The cell wanted is in this merged range
@@ -386,7 +409,7 @@ public class SheetUtil {
}
}
}
-
+
// If we get here, then the cell isn't defined, and doesn't
// live within any merged regions
return null;