问题场景
用户需要导出一份统计名单表格,但内容由模板excel循环得到,内容大小不一致,但循环行高一致。导致用户每次导出打印excel文件时需进行手动调整行高。
现在需要在文件导出前进行自适应行高设置。
解决代码
这里设置起始行号,用于跳过表头的行高变动。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
String inputFilePath = "C:\\Users\\Administrator\\Desktop\\input.xlsx";
String outputFilePath = "C:\\Users\\Administrator\\Desktop\\out.xlsx";
int startRow = 5; // 指定起始行号
try (FileInputStream fis = new FileInputStream(new File(inputFilePath));
Workbook workbook = new XSSFWorkbook(fis)) {
// 调用方法处理工作簿
processWorkbook(workbook, startRow);
// 将处理后的工作簿写入输出文件
try (FileOutputStream fos = new FileOutputStream(new File(outputFilePath))) {
workbook.write(fos);
}
System.out.println("Excel文件已处理并保存到:" + outputFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 处理工作簿
* @param workbook 需要处理的工作簿
* @param startRow 起始行号
*/
public static void processWorkbook(Workbook workbook, int startRow) {
Sheet sheet = workbook.getSheetAt(0);
XSSFSheet xssfSheet = (XSSFSheet) sheet;
// 从指定行开始处理
for (int rowIndex = startRow; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null) {
cellAndSetRowHeight(xssfSheet, (XSSFRow) row);
}
}
}
/**
* 设置单元格和行高
* @param sheet 工作表
* @param sourceRow 需要处理的行
*/
public static void cellAndSetRowHeight(Sheet sheet, XSSFRow sourceRow) {
int count = 1;
int maxColumnIndex = 30;
for (int cellIndex = sourceRow.getFirstCellNum(); cellIndex < sourceRow.getPhysicalNumberOfCells(); cellIndex++, count++) {
if (cellIndex < 0) continue;
XSSFCell sourceCell = sourceRow.getCell(cellIndex);
if (sourceCell == null) continue;
// 获取单元格内容
String cellContent = getCellContentAsString(sourceCell);
if (cellContent == null || cellContent.isEmpty()) {
continue;
}
// 获取单元格宽度信息
Map<String, Object> cellInfoMap = getCellInfo(sourceCell);
Integer cellWidth = (Integer) cellInfoMap.get("width");
// 处理非合并单元格
if (getMergeColumNum(sourceCell, sheet) != 1) {
sheet.setColumnWidth(maxColumnIndex + count, cellWidth);
XSSFCell cell = sourceRow.createCell(maxColumnIndex + count);
CellStyle newStyle = sheet.getWorkbook().createCellStyle();
copyCellStyle(sourceCell.getCellStyle(), newStyle);
cell.setCellStyle(newStyle);
cell.setCellValue(getCellContentAsString(sourceCell));
}
}
sourceRow.getCTRow().setCustomHeight(false);
for (int i = 30; i < 60; i++) {
sheet.setColumnHidden(i, true);
}
}
/**
* 获取单元格内容为字符串
* @param cell 单元格
* @return 单元格内容字符串
*/
public static String getCellContentAsString(XSSFCell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return "";
}
}
/**
* 获取单元格信息
* @param cell 单元格
* @return 单元格信息
*/
public static Map<String, Object> getCellInfo(XSSFCell cell) {
Map<String, Object> cellInfo = new HashMap<>();
cellInfo.put("width", cell.getColumnIndex());
return cellInfo;
}
/**
* 获取合并单元格数量
* @param cell 单元格
* @param sheet 工作表
* @return 合并单元格数量
*/
public static int getMergeColumNum(XSSFCell cell, Sheet sheet) {
// 这里实现合并单元格的逻辑
int mergedColumnCount = 1;
return mergedColumnCount;
}
/**
* 复制单元格样式
* @param sourceStyle 源样式
* @param targetStyle 目标样式
*/
public static void copyCellStyle(CellStyle sourceStyle, CellStyle targetStyle) {
targetStyle.cloneStyleFrom(sourceStyle);
}
}