use cached formula result when autosizing sheet columns, see Bugzilla 50211
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1033005 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9a2fdbd473
commit
13920dccd6
@ -1371,9 +1371,14 @@ Examples:
|
||||
<section><title>Adjust column width to fit the contents</title>
|
||||
<source>
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
sheet.autoSizeColumn((short)0); //adjust width of the first column
|
||||
sheet.autoSizeColumn((short)1); //adjust width of the second column
|
||||
sheet.autoSizeColumn(0); //adjust width of the first column
|
||||
sheet.autoSizeColumn(1); //adjust width of the second column
|
||||
</source>
|
||||
<p>
|
||||
Note, that Sheet#autoSizeColumn() does not evaluate formula cells,
|
||||
the width of formula cells is calculated based on the cached formula result.
|
||||
If your workbook has many formulas then it is a good idea to evaluate them before auto-sizing.
|
||||
</p>
|
||||
<warning>
|
||||
To calculate column width HSSFSheet.autoSizeColumn uses Java2D classes
|
||||
that throw exception if graphical environment is not available. In case if graphical environment
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
<changes>
|
||||
<release version="3.8-beta1" date="2010-??-??">
|
||||
<action dev="poi-developers" type="fix">49761 - Tolerate Double.NaN when reading .xls files</action>
|
||||
<action dev="poi-developers" type="fix">50211 - Use cached formula result when auto-sizing formula cells</action>
|
||||
<action dev="poi-developers" type="fix">50118 - OLE2 does allow a directory with an empty name, so support this in POIFS</action>
|
||||
<action dev="poi-developers" type="fix">50119 - avoid NPE when XSSFReader comes across chart sheets</action>
|
||||
</release>
|
||||
|
@ -54,6 +54,7 @@ import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.util.SSCellRange;
|
||||
import org.apache.poi.ss.util.SheetUtil;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
@ -1146,7 +1147,8 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
|
||||
}
|
||||
|
||||
//only shift if the region outside the shifted rows is not merged too
|
||||
if (!containsCell(merged, startRow-1, 0) && !containsCell(merged, endRow+1, 0)){
|
||||
if (!SheetUtil.containsCell(merged, startRow-1, 0) &&
|
||||
!SheetUtil.containsCell(merged, endRow+1, 0)){
|
||||
merged.setFirstRow(merged.getFirstRow()+n);
|
||||
merged.setLastRow(merged.getLastRow()+n);
|
||||
//have to remove/add it back
|
||||
@ -1164,14 +1166,6 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
|
||||
this.addMergedRegion(region);
|
||||
}
|
||||
}
|
||||
private static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
|
||||
if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
|
||||
&& cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts rows between startRow and endRow n number of rows.
|
||||
@ -1741,153 +1735,8 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
|
||||
* @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
|
||||
*/
|
||||
public void autoSizeColumn(int column, boolean useMergedCells) {
|
||||
AttributedString str;
|
||||
TextLayout layout;
|
||||
/**
|
||||
* Excel measures columns in units of 1/256th of a character width
|
||||
* but the docs say nothing about what particular character is used.
|
||||
* '0' looks to be a good choice.
|
||||
*/
|
||||
char defaultChar = '0';
|
||||
|
||||
/**
|
||||
* This is the multiple that the font height is scaled by when determining the
|
||||
* boundary of rotated text.
|
||||
*/
|
||||
double fontHeightMultiple = 2.0;
|
||||
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
|
||||
HSSFWorkbook wb = HSSFWorkbook.create(_book); // TODO - is it important to not use _workbook?
|
||||
HSSFDataFormatter formatter = new HSSFDataFormatter();
|
||||
HSSFFont defaultFont = wb.getFontAt((short) 0);
|
||||
|
||||
str = new AttributedString("" + defaultChar);
|
||||
copyAttributes(defaultFont, str, 0, 1);
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
int defaultCharWidth = (int)layout.getAdvance();
|
||||
|
||||
double width = -1;
|
||||
rows:
|
||||
for (Iterator<Row> it = rowIterator(); it.hasNext();) {
|
||||
HSSFRow row = (HSSFRow) it.next();
|
||||
HSSFCell cell = row.getCell(column);
|
||||
|
||||
if (cell == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int colspan = 1;
|
||||
for (int i = 0 ; i < getNumMergedRegions(); i++) {
|
||||
CellRangeAddress region = getMergedRegion(i);
|
||||
if (containsCell(region, row.getRowNum(), column)) {
|
||||
if (!useMergedCells) {
|
||||
// If we're not using merged cells, skip this one and move on to the next.
|
||||
continue rows;
|
||||
}
|
||||
cell = row.getCell(region.getFirstColumn());
|
||||
colspan = 1 + region.getLastColumn() - region.getFirstColumn();
|
||||
}
|
||||
}
|
||||
|
||||
HSSFCellStyle style = cell.getCellStyle();
|
||||
int cellType = cell.getCellType();
|
||||
if(cellType == HSSFCell.CELL_TYPE_FORMULA) cellType = cell.getCachedFormulaResultType();
|
||||
|
||||
HSSFFont font = wb.getFontAt(style.getFontIndex());
|
||||
|
||||
if (cellType == HSSFCell.CELL_TYPE_STRING) {
|
||||
HSSFRichTextString rt = cell.getRichStringCellValue();
|
||||
String[] lines = rt.getString().split("\\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String txt = lines[i] + defaultChar;
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
if (rt.numFormattingRuns() > 0) {
|
||||
for (int j = 0; j < lines[i].length(); j++) {
|
||||
int idx = rt.getFontAtIndex(j);
|
||||
if (idx != 0) {
|
||||
HSSFFont fnt = wb.getFontAt((short) idx);
|
||||
copyAttributes(fnt, str, j, j + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String sval = null;
|
||||
if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
|
||||
// Try to get it formatted to look the same as excel
|
||||
try {
|
||||
sval = formatter.formatCellValue(cell);
|
||||
} catch (Exception e) {
|
||||
sval = "" + cell.getNumericCellValue();
|
||||
}
|
||||
} else if (cellType == HSSFCell.CELL_TYPE_BOOLEAN) {
|
||||
sval = String.valueOf(cell.getBooleanCellValue());
|
||||
}
|
||||
if(sval != null) {
|
||||
String txt = sval + defaultChar;
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (width != -1) {
|
||||
width *= 256;
|
||||
if (width > Short.MAX_VALUE) { //width can be bigger that Short.MAX_VALUE!
|
||||
width = Short.MAX_VALUE;
|
||||
}
|
||||
_sheet.setColumnWidth(column, (short) (width));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy text attributes from the supplied HSSFFont to Java2D AttributedString
|
||||
*/
|
||||
private void copyAttributes(HSSFFont font, AttributedString str, int startIdx, int endIdx) {
|
||||
str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
|
||||
str.addAttribute(TextAttribute.SIZE, new Float(font.getFontHeightInPoints()));
|
||||
if (font.getBoldweight() == HSSFFont.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
|
||||
if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
|
||||
if (font.getUnderline() == HSSFFont.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
|
||||
double width = SheetUtil.getColumnWidth(this, column, useMergedCells);
|
||||
if(width != -1) setColumnWidth(column, (int) (256*width));
|
||||
}
|
||||
|
||||
/**
|
||||
|
219
src/java/org/apache/poi/ss/util/SheetUtil.java
Executable file
219
src/java/org/apache/poi/ss/util/SheetUtil.java
Executable file
@ -0,0 +1,219 @@
|
||||
/* ====================================================================
|
||||
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.ss.util;
|
||||
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
|
||||
import java.text.AttributedString;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.geom.AffineTransform;
|
||||
|
||||
|
||||
/**
|
||||
* Helper methods for when working with Usermodel sheets
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class SheetUtil {
|
||||
|
||||
/**
|
||||
* Excel measures columns in units of 1/256th of a character width
|
||||
* but the docs say nothing about what particular character is used.
|
||||
* '0' looks to be a good choice.
|
||||
*/
|
||||
private static final char defaultChar = '0';
|
||||
|
||||
/**
|
||||
* This is the multiple that the font height is scaled by when determining the
|
||||
* boundary of rotated text.
|
||||
*/
|
||||
private static final double fontHeightMultiple = 2.0;
|
||||
|
||||
/**
|
||||
* Dummy formula evaluator that does nothing.
|
||||
* YK: The only reason of having this class is that
|
||||
* {@link org.apache.poi.ss.usermodel.DataFormatter#formatCellValue(org.apache.poi.ss.usermodel.Cell)}
|
||||
* returns formula string for formula cells. Dummy evaluator makes it to format the cached formula result.
|
||||
*
|
||||
* See Bugzilla #50021
|
||||
*/
|
||||
private static final FormulaEvaluator dummyEvaluator = new FormulaEvaluator(){
|
||||
public void clearAllCachedResultValues(){}
|
||||
public void notifySetFormula(Cell cell) {}
|
||||
public void notifyDeleteCell(Cell cell) {}
|
||||
public void notifyUpdateCell(Cell cell) {}
|
||||
public CellValue evaluate(Cell cell) {return null; }
|
||||
public Cell evaluateInCell(Cell cell) { return null; }
|
||||
|
||||
public int evaluateFormulaCell(Cell cell) {
|
||||
return cell.getCachedFormulaResultType();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* drawing context to measure text
|
||||
*/
|
||||
private static final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);
|
||||
|
||||
/**
|
||||
* Compute width of a column and return the result
|
||||
*
|
||||
* @param sheet the sheet to calculate
|
||||
* @param column 0-based index of the column
|
||||
* @param useMergedCells whether to use merged cells
|
||||
* @return the width in pixels
|
||||
*/
|
||||
public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells){
|
||||
AttributedString str;
|
||||
TextLayout layout;
|
||||
|
||||
Workbook wb = sheet.getWorkbook();
|
||||
DataFormatter formatter = new DataFormatter();
|
||||
Font defaultFont = wb.getFontAt((short) 0);
|
||||
|
||||
str = new AttributedString(String.valueOf(defaultChar));
|
||||
copyAttributes(defaultFont, str, 0, 1);
|
||||
layout = new TextLayout(str.getIterator(), fontRenderContext);
|
||||
int defaultCharWidth = (int)layout.getAdvance();
|
||||
|
||||
double width = -1;
|
||||
rows:
|
||||
for (Row row : sheet) {
|
||||
Cell cell = row.getCell(column);
|
||||
|
||||
if (cell == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int colspan = 1;
|
||||
for (int i = 0 ; i < sheet.getNumMergedRegions(); i++) {
|
||||
CellRangeAddress region = sheet.getMergedRegion(i);
|
||||
if (containsCell(region, row.getRowNum(), column)) {
|
||||
if (!useMergedCells) {
|
||||
// If we're not using merged cells, skip this one and move on to the next.
|
||||
continue rows;
|
||||
}
|
||||
cell = row.getCell(region.getFirstColumn());
|
||||
colspan = 1 + region.getLastColumn() - region.getFirstColumn();
|
||||
}
|
||||
}
|
||||
|
||||
CellStyle style = cell.getCellStyle();
|
||||
int cellType = cell.getCellType();
|
||||
|
||||
// for formula cells we compute the cell width for the cached formula result
|
||||
if(cellType == Cell.CELL_TYPE_FORMULA) cellType = cell.getCachedFormulaResultType();
|
||||
|
||||
Font font = wb.getFontAt(style.getFontIndex());
|
||||
|
||||
if (cellType == Cell.CELL_TYPE_STRING) {
|
||||
RichTextString rt = cell.getRichStringCellValue();
|
||||
String[] lines = rt.getString().split("\\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String txt = lines[i] + defaultChar;
|
||||
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
if (rt.numFormattingRuns() > 0) {
|
||||
// TODO: support rich text fragments
|
||||
}
|
||||
|
||||
layout = new TextLayout(str.getIterator(), fontRenderContext);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String sval = null;
|
||||
if (cellType == Cell.CELL_TYPE_NUMERIC) {
|
||||
// Try to get it formatted to look the same as excel
|
||||
try {
|
||||
sval = formatter.formatCellValue(cell, dummyEvaluator);
|
||||
} catch (Exception e) {
|
||||
sval = String.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
} else if (cellType == Cell.CELL_TYPE_BOOLEAN) {
|
||||
sval = String.valueOf(cell.getBooleanCellValue()).toUpperCase();
|
||||
}
|
||||
if(sval != null) {
|
||||
String txt = sval + defaultChar;
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
layout = new TextLayout(str.getIterator(), fontRenderContext);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy text attributes from the supplied Font to Java2D AttributedString
|
||||
*/
|
||||
private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) {
|
||||
str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
|
||||
str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
|
||||
if (font.getBoldweight() == Font.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
|
||||
if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
|
||||
if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
|
||||
}
|
||||
|
||||
public static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
|
||||
if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
|
||||
&& cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -49,10 +49,7 @@ import org.apache.poi.ss.usermodel.Footer;
|
||||
import org.apache.poi.ss.usermodel.Header;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.util.SSCellRange;
|
||||
import org.apache.poi.ss.util.*;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
@ -334,7 +331,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||
* @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
|
||||
*/
|
||||
public void autoSizeColumn(int column, boolean useMergedCells) {
|
||||
double width = ColumnHelper.getColumnWidth(this, column, useMergedCells);
|
||||
double width = SheetUtil.getColumnWidth(this, column, useMergedCells);
|
||||
if(width != -1){
|
||||
columnHelper.setColBestFit(column, true);
|
||||
columnHelper.setCustomWidth(column, true);
|
||||
|
@ -299,169 +299,4 @@ public class ColumnHelper {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getColumnWidth(XSSFSheet sheet, int column, boolean useMergedCells){
|
||||
AttributedString str;
|
||||
TextLayout layout;
|
||||
/**
|
||||
* Excel measures columns in units of 1/256th of a character width
|
||||
* but the docs say nothing about what particular character is used.
|
||||
* '0' looks to be a good choice.
|
||||
*/
|
||||
char defaultChar = '0';
|
||||
|
||||
/**
|
||||
* This is the multiple that the font height is scaled by when determining the
|
||||
* boundary of rotated text.
|
||||
*/
|
||||
double fontHeightMultiple = 2.0;
|
||||
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
|
||||
XSSFWorkbook wb = sheet.getWorkbook();
|
||||
XSSFFont defaultFont = wb.getFontAt((short) 0);
|
||||
|
||||
str = new AttributedString("" + defaultChar);
|
||||
copyAttributes(defaultFont, str, 0, 1);
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
int defaultCharWidth = (int)layout.getAdvance();
|
||||
|
||||
double width = -1;
|
||||
rows:
|
||||
for (Iterator it = sheet.rowIterator(); it.hasNext();) {
|
||||
XSSFRow row = (XSSFRow) it.next();
|
||||
XSSFCell cell = row.getCell(column);
|
||||
|
||||
if (cell == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int colspan = 1;
|
||||
for (int i = 0 ; i < sheet.getNumMergedRegions(); i++) {
|
||||
CellRangeAddress region = sheet.getMergedRegion(i);
|
||||
if (containsCell(region, row.getRowNum(), column)) {
|
||||
if (!useMergedCells) {
|
||||
// If we're not using merged cells, skip this one and move on to the next.
|
||||
continue rows;
|
||||
}
|
||||
cell = row.getCell(region.getFirstColumn());
|
||||
colspan = 1 + region.getLastColumn() - region.getFirstColumn();
|
||||
}
|
||||
}
|
||||
|
||||
XSSFCellStyle style = cell.getCellStyle();
|
||||
int cellType = cell.getCellType();
|
||||
if(cellType == XSSFCell.CELL_TYPE_FORMULA) cellType = cell.getCachedFormulaResultType();
|
||||
XSSFFont font = wb.getFontAt(style.getFontIndex());
|
||||
|
||||
if (cellType == XSSFCell.CELL_TYPE_STRING) {
|
||||
XSSFRichTextString rt = cell.getRichStringCellValue();
|
||||
String[] lines = rt.getString().split("\\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String txt = lines[i] + defaultChar;
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
if (rt.numFormattingRuns() > 0) {
|
||||
int pos = 0;
|
||||
for (int j = 0; j < rt.numFormattingRuns(); j++) {
|
||||
XSSFFont fnt = rt.getFontOfFormattingRun(j);
|
||||
if (fnt != null) {
|
||||
int len = rt.getLengthOfFormattingRun(j);
|
||||
if(len > 0) { //ignore degenerate zero-length runs
|
||||
copyAttributes(fnt, str, pos, pos + len);
|
||||
pos += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String sval = null;
|
||||
if (cellType == XSSFCell.CELL_TYPE_NUMERIC) {
|
||||
String dfmt = style.getDataFormatString();
|
||||
String format = dfmt == null ? null : dfmt.replaceAll("\"", "");
|
||||
double value = cell.getNumericCellValue();
|
||||
try {
|
||||
NumberFormat fmt;
|
||||
if ("General".equals(format))
|
||||
sval = "" + value;
|
||||
else
|
||||
{
|
||||
fmt = new DecimalFormat(format);
|
||||
sval = fmt.format(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sval = "" + value;
|
||||
}
|
||||
} else if (cellType == XSSFCell.CELL_TYPE_BOOLEAN) {
|
||||
sval = String.valueOf(cell.getBooleanCellValue());
|
||||
}
|
||||
if(sval != null) {
|
||||
String txt = sval + defaultChar;
|
||||
str = new AttributedString(txt);
|
||||
copyAttributes(font, str, 0, txt.length());
|
||||
|
||||
layout = new TextLayout(str.getIterator(), frc);
|
||||
if(style.getRotation() != 0){
|
||||
/*
|
||||
* Transform the text using a scale so that it's height is increased by a multiple of the leading,
|
||||
* and then rotate the text before computing the bounds. The scale results in some whitespace around
|
||||
* the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
|
||||
* is added by the standard Excel autosize.
|
||||
*/
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
|
||||
trans.concatenate(
|
||||
AffineTransform.getScaleInstance(1, fontHeightMultiple)
|
||||
);
|
||||
width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
} else {
|
||||
width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy text attributes from the supplied HSSFFont to Java2D AttributedString
|
||||
*/
|
||||
private static void copyAttributes(XSSFFont font, AttributedString str, int startIdx, int endIdx) {
|
||||
str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
|
||||
str.addAttribute(TextAttribute.SIZE, new Float(font.getFontHeightInPoints()));
|
||||
if (font.getBoldweight() == XSSFFont.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
|
||||
if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
|
||||
if (font.getUnderline() == XSSFFont.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
|
||||
}
|
||||
|
||||
private static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
|
||||
if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
|
||||
&& cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* ====================================================================
|
||||
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.xssf.usermodel;
|
||||
|
||||
import org.apache.poi.ss.usermodel.BaseTestSheetAutosizeColumn;
|
||||
import org.apache.poi.xssf.XSSFITestDataProvider;
|
||||
|
||||
/**
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class TestXSSFSheetAutosizeColumn extends BaseTestSheetAutosizeColumn {
|
||||
|
||||
public TestXSSFSheetAutosizeColumn(){
|
||||
super(XSSFITestDataProvider.instance);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/* ====================================================================
|
||||
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.usermodel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.apache.poi.ddf.EscherDgRecord;
|
||||
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.DrawingManager2;
|
||||
import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
import org.apache.poi.hssf.model.InternalSheet;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock;
|
||||
import org.apache.poi.hssf.usermodel.RecordInspector.RecordCollector;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.util.TempFile;
|
||||
|
||||
/**
|
||||
* Test auto-sizing columns in HSSF
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class TestHSSFSheetAutosizeColumn extends BaseTestSheetAutosizeColumn {
|
||||
|
||||
public TestHSSFSheetAutosizeColumn() {
|
||||
super(HSSFITestDataProvider.instance);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,255 @@
|
||||
/* ====================================================================
|
||||
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.ss.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ss.ITestDataProvider;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Common superclass for testing automatic sizing of sheet columns
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
|
||||
private final ITestDataProvider _testDataProvider;
|
||||
|
||||
protected BaseTestSheetAutosizeColumn(ITestDataProvider testDataProvider) {
|
||||
_testDataProvider = testDataProvider;
|
||||
}
|
||||
|
||||
// TODO should we have this stuff in the FormulaEvaluator?
|
||||
private void evaluateWorkbook(Workbook workbook){
|
||||
FormulaEvaluator eval = workbook.getCreationHelper().createFormulaEvaluator();
|
||||
for(int i=0; i < workbook.getNumberOfSheets(); i++) {
|
||||
Sheet sheet = workbook.getSheetAt(i);
|
||||
for (Row r : sheet) {
|
||||
for (Cell c : r) {
|
||||
if (c.getCellType() == Cell.CELL_TYPE_FORMULA){
|
||||
eval.evaluateFormulaCell(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testNumericCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
DataFormat df = workbook.getCreationHelper().createDataFormat();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
row.createCell(0).setCellValue(0); // getCachedFormulaResult() returns 0 for not evaluated formula cells
|
||||
row.createCell(1).setCellValue(10);
|
||||
row.createCell(2).setCellValue("10");
|
||||
row.createCell(3).setCellFormula("(A1+B1)*1.0"); // a formula that returns '10'
|
||||
|
||||
Cell cell4 = row.createCell(4); // numeric cell with a custom style
|
||||
CellStyle style4 = workbook.createCellStyle();
|
||||
style4.setDataFormat(df.getFormat("0.0000"));
|
||||
cell4.setCellStyle(style4);
|
||||
cell4.setCellValue(10); // formatted as '10.0000'
|
||||
|
||||
row.createCell(5).setCellValue("10.0000");
|
||||
|
||||
// autosize not-evaluated cells, formula cells are sized as if the result is 0
|
||||
for (int i = 0; i < 6; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertTrue(sheet.getColumnWidth(0) < sheet.getColumnWidth(1)); // width of '0' is less then width of '10'
|
||||
assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // 10 and '10' should be sized equally
|
||||
assertEquals(sheet.getColumnWidth(3), sheet.getColumnWidth(0)); // formula result is unknown, the width is calculated for '0'
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(5)); // 10.0000 and '10.0000'
|
||||
|
||||
// evaluate formulas and re-autosize
|
||||
evaluateWorkbook(workbook);
|
||||
|
||||
for (int i = 0; i < 6; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertTrue(sheet.getColumnWidth(0) < sheet.getColumnWidth(1)); // width of '0' is less then width of '10'
|
||||
assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // columns 1, 2 and 3 should have the same width
|
||||
assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(3)); // columns 1, 2 and 3 should have the same width
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(5)); // 10.0000 and '10.0000'
|
||||
}
|
||||
|
||||
public void testBooleanCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
row.createCell(0).setCellValue(0); // getCachedFormulaResult() returns 0 for not evaluated formula cells
|
||||
row.createCell(1).setCellValue(true);
|
||||
row.createCell(2).setCellValue("TRUE");
|
||||
row.createCell(3).setCellFormula("1 > 0"); // a formula that returns true
|
||||
|
||||
// autosize not-evaluated cells, formula cells are sized as if the result is 0
|
||||
for (int i = 0; i < 4; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertTrue(sheet.getColumnWidth(1) > sheet.getColumnWidth(0)); // 'true' is wider than '0'
|
||||
assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // 10 and '10' should be sized equally
|
||||
assertEquals(sheet.getColumnWidth(3), sheet.getColumnWidth(0)); // formula result is unknown, the width is calculated for '0'
|
||||
|
||||
// evaluate formulas and re-autosize
|
||||
evaluateWorkbook(workbook);
|
||||
|
||||
for (int i = 0; i < 4; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertTrue(sheet.getColumnWidth(1) > sheet.getColumnWidth(0)); // 'true' is wider than '0'
|
||||
assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // columns 1, 2 and 3 should have the same width
|
||||
assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(3)); // columns 1, 2 and 3 should have the same width
|
||||
}
|
||||
|
||||
public void testDateCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
DataFormat df = workbook.getCreationHelper().createDataFormat();
|
||||
|
||||
CellStyle style1 = workbook.createCellStyle();
|
||||
style1.setDataFormat(df.getFormat("m"));
|
||||
|
||||
CellStyle style3 = workbook.createCellStyle();
|
||||
style3.setDataFormat(df.getFormat("mmm"));
|
||||
|
||||
CellStyle style5 = workbook.createCellStyle(); //rotated text
|
||||
style5.setDataFormat(df.getFormat("mmm/dd/yyyy"));
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(2010, 0, 1); // Jan 1 2010
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
row.createCell(0).setCellValue(DateUtil.getJavaDate(0)); //default date
|
||||
|
||||
Cell cell1 = row.createCell(1);
|
||||
cell1.setCellValue(calendar);
|
||||
cell1.setCellStyle(style1);
|
||||
row.createCell(2).setCellValue("1"); // column 1 should be sized as '1'
|
||||
|
||||
Cell cell3 = row.createCell(3);
|
||||
cell3.setCellValue(calendar);
|
||||
cell3.setCellStyle(style3);
|
||||
row.createCell(4).setCellValue("Jan");
|
||||
|
||||
Cell cell5 = row.createCell(5);
|
||||
cell5.setCellValue(calendar);
|
||||
cell5.setCellStyle(style5);
|
||||
row.createCell(6).setCellValue("Jan/01/2010");
|
||||
|
||||
Cell cell7 = row.createCell(7);
|
||||
cell7.setCellFormula("DATE(2010,1,1)");
|
||||
cell7.setCellStyle(style3); // should be sized as 'Jan'
|
||||
|
||||
// autosize not-evaluated cells, formula cells are sized as if the result is 0
|
||||
for (int i = 0; i < 8; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(1)); // date formatted as 'm'
|
||||
assertTrue(sheet.getColumnWidth(3) > sheet.getColumnWidth(1)); // 'mmm' is wider than 'm'
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(3)); // date formatted as 'mmm'
|
||||
assertTrue(sheet.getColumnWidth(5) > sheet.getColumnWidth(3)); // 'mmm/dd/yyyy' is wider than 'mmm'
|
||||
assertEquals(sheet.getColumnWidth(6), sheet.getColumnWidth(5)); // date formatted as 'mmm/dd/yyyy'
|
||||
|
||||
// YK: width of not-evaluated formulas that return data is not determined
|
||||
// POI seems to conevert '0' to Excel date which is the beginng of the Excel's date system
|
||||
|
||||
// evaluate formulas and re-autosize
|
||||
evaluateWorkbook(workbook);
|
||||
|
||||
for (int i = 0; i < 8; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(1)); // date formatted as 'm'
|
||||
assertTrue(sheet.getColumnWidth(3) > sheet.getColumnWidth(1)); // 'mmm' is wider than 'm'
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(3)); // date formatted as 'mmm'
|
||||
assertTrue(sheet.getColumnWidth(5) > sheet.getColumnWidth(3)); // 'mmm/dd/yyyy' is wider than 'mmm'
|
||||
assertEquals(sheet.getColumnWidth(6), sheet.getColumnWidth(5)); // date formatted as 'mmm/dd/yyyy'
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(7)); // date formula formatted as 'mmm'
|
||||
}
|
||||
|
||||
public void testStringCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
Row row = sheet.createRow(0);
|
||||
|
||||
Font defaultFont = workbook.getFontAt((short)0);
|
||||
|
||||
CellStyle style1 = workbook.createCellStyle();
|
||||
Font font1 = workbook.createFont();
|
||||
font1.setFontHeight((short)(2*defaultFont.getFontHeight()));
|
||||
style1.setFont(font1);
|
||||
|
||||
row.createCell(0).setCellValue("x");
|
||||
row.createCell(1).setCellValue("xxxx");
|
||||
row.createCell(2).setCellValue("xxxxxxxxxxxx");
|
||||
row.createCell(3).setCellValue("Apache\nSoftware Foundation"); // the text is splitted into two lines
|
||||
row.createCell(4).setCellValue("Software Foundation");
|
||||
|
||||
Cell cell5 = row.createCell(5);
|
||||
cell5.setCellValue("Software Foundation");
|
||||
cell5.setCellStyle(style1); // same as in column 4 but the font is twice larger than the default font
|
||||
|
||||
for (int i = 0; i < 10; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
assertTrue(2*sheet.getColumnWidth(0) < sheet.getColumnWidth(1)); // width is roughly proportional to the number of characters
|
||||
assertTrue(2*sheet.getColumnWidth(1) < sheet.getColumnWidth(2));
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(3));
|
||||
assertTrue(sheet.getColumnWidth(5) > sheet.getColumnWidth(4)); //larger font results in a wider column width
|
||||
}
|
||||
|
||||
public void testRotatedText(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
Row row = sheet.createRow(0);
|
||||
|
||||
CellStyle style1 = workbook.createCellStyle();
|
||||
style1.setRotation((short)90);
|
||||
|
||||
Cell cell0 = row.createCell(0);
|
||||
cell0.setCellValue("Apache Software Foundation");
|
||||
cell0.setCellStyle(style1);
|
||||
|
||||
Cell cell1 = row.createCell(1);
|
||||
cell1.setCellValue("Apache Software Foundation");
|
||||
|
||||
for (int i = 0; i < 2; i++) sheet.autoSizeColumn(i);
|
||||
|
||||
int w0 = sheet.getColumnWidth(0);
|
||||
int w1 = sheet.getColumnWidth(1);
|
||||
|
||||
assertTrue(w0*5 < w1); // rotated text occupies at least five times less horizontal space than normal text
|
||||
}
|
||||
|
||||
public void testMergedCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
sheet.addMergedRegion(CellRangeAddress.valueOf("A1:B1"));
|
||||
|
||||
Cell cell0 = row.createCell(0);
|
||||
cell0.setCellValue("Apache Software Foundation");
|
||||
|
||||
int defaulWidth = sheet.getColumnWidth(0);
|
||||
sheet.autoSizeColumn(0);
|
||||
// column is unchanged if merged regions are ignored (Excel like behavior)
|
||||
assertEquals(defaulWidth, sheet.getColumnWidth(0));
|
||||
|
||||
sheet.autoSizeColumn(0, true);
|
||||
assertTrue(sheet.getColumnWidth(0) > defaulWidth);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user