Java 导出Excel根据单元格内容计算并设置列宽度、行高
话不多说,上代码:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 根据单元格内容计算并设置列宽度、行高
*/
public class ExcelUtil {
// sheet.setColumnWidth()参数的单位是1/256个字符宽度,这里使用300计算用于保留部分空白位置
public static final Integer CELL_CARDINAL = 300;
/**
* 根据单元格内容计算并设置列宽度
*
* @param sheet 需要设置的Sheet对象
* @param cellValue 单元格内容
* @param cellIndex 单元格下标
* @param allCellWidthMap 所有需要设定的单元格列宽度
* @return 所有需要设定的单元格列宽度
*/
public static Map<Integer, Integer> setCellWidth(Sheet sheet, String cellValue, int cellIndex, Map<Integer, Integer> allCellWidthMap) {
if (StringUtils.isBlank(cellValue)) {
return allCellWidthMap;
}
// 根据单元格内容计算宽度
Integer cellWidth = cellValue.getBytes().length * CELL_CARDINAL;
// 限定最大宽度
int maxCellWidth = 60 * CELL_CARDINAL;
Integer oldCellWidth = allCellWidthMap.get(cellIndex);
if (Objects.nonNull(oldCellWidth)) {
// 当前宽度不超过已设定宽度时,保留原宽度
if (oldCellWidth > cellWidth) {
cellWidth = oldCellWidth;
}
// 宽度超过最大限度时,使用最大宽度限度
// 如果需要全部展示单元格内容可使用setWrapText(true)设置单元格自动换行
if (cellWidth > maxCellWidth) {
cellWidth = maxCellWidth;
}
}
sheet.setColumnWidth(cellIndex, cellWidth);
allCellWidthMap.put(cellIndex, cellWidth);
return allCellWidthMap;
}
/**
* 设置并获取单元格样式
*
* @param workbook
* @return 单元格样式
*/
public static CellStyle getCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 左对齐
//style.setAlignment(HorizontalAlignment.LEFT);
// 居中
style.setAlignment(HorizontalAlignment.CENTER);
/*//设置解析格式
DataFormat format = workbook.createDataFormat();
style.setDataFormat(format.getFormat("@"));*/
// 自动换行
style.setWrapText(true);
/*// 设置背景色
style.setFillForegroundColor(IndexedColors.RED.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);*/
/*// 单元格是否锁定
style.setLocked(false);*/
return style;
}
/**
* 根据单元格内容计算并设置行高
*
* @param sourceRow
*/
public static void setRowHeight(Row sourceRow) {
double maxHeight = sourceRow.getHeight();
for (int cellIndex = sourceRow.getFirstCellNum(); cellIndex <= sourceRow.getPhysicalNumberOfCells(); cellIndex++) {
if (cellIndex < 0) {
continue;
}
Cell sourceCell = sourceRow.getCell(cellIndex);
String cellContent = getCellContentAsString(sourceCell);
if (StringUtils.isBlank(cellContent)) {
continue;
}
//单元格的宽高及单元格信息
Map<String, Object> cellInfoMap = getCellInfo(sourceCell);
Integer cellWidth = (Integer) cellInfoMap.get("width");
Integer cellHeight = (Integer) cellInfoMap.get("height");
if (cellHeight > maxHeight) {
maxHeight = cellHeight;
}
//XSSFCellStyle cellStyle = sourceCell.getCellStyle();
//XSSFFont font = cellStyle.getFont();
//short fontHeight = font.getFontHeight();
//int cellContentWidth = cellContent.getBytes().length * 256;
int cellContentWidth = cellContent.getBytes().length * CELL_CARDINAL;
int stringNeedsRows = cellContentWidth / cellWidth + 1;
double stringNeedsHeight = (double) cellHeight * stringNeedsRows;
if (stringNeedsHeight > maxHeight) {
maxHeight = stringNeedsHeight;
/*if (maxHeight / cellHeight > 5) {
maxHeight = 4 * cellHeight;
}*/
maxHeight = Math.ceil(maxHeight);
/*Boolean isPartOfRowsRegion = (Boolean) cellInfoMap.get("isPartOfRowsRegion");
if (isPartOfRowsRegion) {
Integer firstRow = (Integer) cellInfoMap.get("firstRow");
Integer lastRow = (Integer) cellInfoMap.get("lastRow");
//平均每行需要增加的行高
double addHeight = (maxHeight - cellHeight) / (lastRow - firstRow + 1);
for (int i = firstRow; i <= lastRow; i++) {
double rowsRegionHeight = sourceRow.getSheet().getRow(i).getHeight() + addHeight;
sourceRow.getSheet().getRow(i).setHeight((short) rowsRegionHeight);
}
} else {
sourceRow.setHeight((short) maxHeight);
}*/
}
}
sourceRow.setHeight((short) maxHeight);
}
private static String getCellContentAsString(Cell cell) {
if (null == cell) {
return "";
}
String result = "";
switch (cell.getCellType()) {
case NUMERIC:
String s = String.valueOf(cell.getNumericCellValue());
if (s != null && s.endsWith(".0")) {
s = s.substring(0, s.length() - 2);
}
result = s;
break;
case STRING:
result = String.valueOf(cell.getRichStringCellValue());
break;
case BLANK:
break;
case BOOLEAN:
result = String.valueOf(cell.getBooleanCellValue());
break;
case ERROR:
break;
default:
break;
}
return result;
}
private static Map<String, Object> getCellInfo(Cell cell) {
Map<String, Object> map = new HashMap();
Sheet sheet = cell.getSheet();
int rowIndex = cell.getRowIndex();
int columnIndex = cell.getColumnIndex();
boolean isPartOfRegion = false;
int firstColumn = 0;
int lastColumn = 0;
int firstRow = 0;
int lastRow = 0;
int sheetMergeCount = sheet.getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress c = sheet.getMergedRegion(i);
firstColumn = c.getFirstColumn();
lastColumn = c.getLastColumn();
firstRow = c.getFirstRow();
lastRow = c.getLastRow();
if (rowIndex >= firstRow && rowIndex <= lastRow) {
if (columnIndex >= firstColumn && columnIndex <= lastColumn) {
isPartOfRegion = true;
break;
}
}
}
Integer width = 0;
Integer height = 0;
boolean isPartOfRowsRegion = false;
if (isPartOfRegion) {
for (int i = firstColumn; i <= lastColumn; i++) {
width += sheet.getColumnWidth(i);
}
for (int i = firstRow; i <= lastRow; i++) {
if (sheet.getRow(i) == null) {
height += sheet.createRow(i).getHeight();
} else {
height += sheet.getRow(i).getHeight();
}
}
if (lastRow > firstRow) {
isPartOfRowsRegion = true;
}
} else {
width = sheet.getColumnWidth(columnIndex);
height += cell.getRow().getHeight();
}
map.put("isPartOfRowsRegion", isPartOfRowsRegion);
map.put("firstRow", firstRow);
map.put("lastRow", lastRow);
map.put("width", width);
map.put("height", height);
return map;
}
}

浙公网安备 33010602011771号