-
模板中设置单元格的自动换行和最合适行高
缺点:这种方式只对未合并的单元格有效。
在registerWriteHandler中设置单元格样式策略
{
// 生成excel文件
EasyExcel.write(saveWordFilePath, DirectoryPrint2BO.class)
.withTemplate(excelFileTemplate)
.needHead(false)
// 单元格样式策略
.registerWriteHandler(this.getHorizontalCellStyleStrategy((short) 12))
.sheet("Sheet1")
.doWrite(directoryPrint2BoList);
}
/**
* 单元格样式策略
*/
public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy(Short fontHeightInPoints) {
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 设置边框
contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
contentWriteCellStyle.setBorderTop(BorderStyle.NONE);
// 配置字体
WriteFont contentWriteFont = new WriteFont();
// 字体
contentWriteFont.setFontName("宋体");
// 字体大小
contentWriteFont.setFontHeightInPoints(fontHeightInPoints);
// 设置加粗
contentWriteFont.setBold(false);
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 【水平居中需要使用以下两行】
// 设置文字左右居中
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// 设置文字上下居中
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置 自动换行
contentWriteCellStyle.setWrapped(true);
// 样式策略
return new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
}
缺点:实现自适应行高的时候,无法保证样式和模板中一致。
在自定义registerWriteHandler通过代码计算字符宽度和行高
通过Graphics2D自动获取字符的像素宽度和高度
public static double calculateStringWidthInPixels(String text, Font font) {
Graphics2D g2d = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).createGraphics();
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(text, frc);
return bounds.getWidth();
}
public static double calculateStringHeightInPixels(String text, Font font) {
Graphics2D g2d = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).createGraphics();
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(text, frc);
return bounds.getHeight();
}
计算字符宽度和所需行高
private void setWrap(Sheet sheet, int rowIndex, int startColIndex, int endColIndex) {
if (ObjectUtils.isEmpty(sheet)){
return;
}
Row r = sheet.getRow(rowIndex);
if (ObjectUtils.isEmpty(r)){
return;
}
Cell c = r.getCell(startColIndex);
if (ObjectUtils.isEmpty(c)){
return;
}
CellStyle cellStyle = c.getCellStyle();
if (ObjectUtils.isEmpty(cellStyle)){
return;
}
// 获取当前字体
Font writeFont = sheet.getWorkbook().getFontAt(cellStyle.getFontIndex());
// 假设我们有一个字符串和字体
String text = c.getStringCellValue();
if (StringUtils.isEmpty(text)){
return;
}
java.awt.Font font = convertToAwtFont(writeFont);
// 计算字符串的像素宽度
double pixelWidth = FillUtil.calculateStringWidthInPixels(text, font);
double pixelHeight = FillUtil.calculateStringHeightInPixels(text, font);
// 假设一个字符在 Excel 中平均占用 100 像素(这个值需要根据实际情况调整)
// 然后计算字符宽度(以 1/256 个字符宽度为单位)
double textWidth = (pixelWidth / 256 * 256);
double textHeight = (pixelHeight / 256 * 256);
if (textWidth <= 0){
return;
}
if (textHeight <= 0){
return;
}
//获取列宽
double totalColWidth = 0;
for (int i = startColIndex; i <= endColIndex; i++) {
float currentColWidth = sheet.getColumnWidthInPixels(i);
totalColWidth += currentColWidth;
}
if (totalColWidth <= 0){
return;
}
float currentRowHeight = r.getHeightInPoints();
//每行除字体外的留白高度
double eachLineBlankHeight = Math.abs(currentRowHeight - textHeight);
if (lineBlankHeightMap.containsKey(rowIndex)){
eachLineBlankHeight = lineBlankHeightMap.get(rowIndex);
}else {
lineBlankHeightMap.put(rowIndex, eachLineBlankHeight);
}
if (textWidth > totalColWidth){
//调整行高
int heightMultiple = (int) Math.ceil(textWidth / totalColWidth);
if (currentRowHeight < (textHeight + eachLineBlankHeight) * heightMultiple){
r.setHeightInPoints((currentRowHeight * heightMultiple));
}
}
}
字符宽度和像素宽度之间比例为1:256,行高和像素高度一致,具体需要自行通过代码中的值和模板中的行高、列宽进行比对来确定;
缺点:实现较为复杂