首页 > 编程语言 >Java 导出Excel根据单元格内容计算并设置列宽度、行高

Java 导出Excel根据单元格内容计算并设置列宽度、行高

时间:2023-10-11 17:55:21浏览次数:42  
标签:Java int 单元格 Excel firstRow 宽度 maxHeight Integer

话不多说,上代码:

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;
    }

}

  

标签:Java,int,单元格,Excel,firstRow,宽度,maxHeight,Integer
From: https://www.cnblogs.com/Big-Boss/p/17757825.html

相关文章

  • 1——of C++ and Java togather
    因为那个C++最全的笔记是从第18课开始做(笔者说18课之前都很基础),所以这里就对前18课的知识做个笔记总结C++的工作过程这里提到的C++工作过程主要涉及两个:编译与链接之前考研时候学到,(在组成原理的某个章节),计算机的工作过程其实就涉及“将源程序转换成可执行文件”,与其中便......
  • java 后台防止重复提交(注解方式)
    /***自定义注解防止表单重复提交**@authorframework*/@Inherited@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceRepeatSubmit{/***间隔时间(ms),小于此时间视为重复提交*/intinterval(......
  • java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a M
    原文链接:https://www.longkui.site/error/java-lang-illegalargumentexception-expected-multiparthttpservletrequest-is-a-multipartresolver-configured/4837/0.背景JAVA后台一个上传excel的接口,如下:importData(@RequestParam("file")MultipartFilefile)然后,前台按......
  • Java程序【生产问题】排查
    1.查看线程数:方法一:查看/proc/[进程ID]/grepThreads/proc/[进程ID]/status方法二:ps-L-opid,tid,comm,state-p[进程ID]2.jstack分析Java堆栈jstack-l[进程ID]3.查看IOeg:如果有toomanyopenfiles的报错,则说明程序打开的文件过多1.查看该进程打开......
  • JavaScript :全局对象
    全局对象是一个常规的JavaScript对象,具有非常重要的用途:该对象的属性是全局定义的标识符,可供JavaScript解释器启动(或每当Web浏览器加载新页面时)使用,它会创建一个新的全局对象对象并为其提供一组初始属性,这些属性定义:全局常量,例如undefined、infinity和NaN。全局函数,如isN......
  • JavaScript之正则表达式
    正则表达式(RegExp)正则表达式不是JS独有的内容,大部分语言都支持正则表达式JS中正则表达式使用得不是那么多,我们可以尽量避免使用正则表达式在JS中,正则表达式就是RegExp对象,RegExp对象用于将文本与一个模式匹配正则表达式(regularexpressions,规则表达式)正则表达式用来定......
  • 又一个难题:Java 序列化和反序列化为什么要实现 Serializable 接口?
    作者:椰子Tyshawn来源:https://blog.csdn.net/litianxiang_kaola最近公司的在做服务化,需要把所有model包里的类都实现Serializable接口,同时还要显示指定serialVersionUID的值.听到这个需求,我脑海里就突然出现了好几个问题,比如说:序列化和反序列化是什么?实现序列化和......
  • 导出excel文件总结
    使用alibaba的easyExcel一定要给要导出的类加注解,例:@ExcelProperty(value="文件传输结果(1=成功,0=失败,2=未传输)")导出的excel文件如果是只有属性没有值,查看自己的查询条件是否由默认值影响了异步导出,先确定好list是否为0,再返回成功如果导出的文件卡住了,也没有异......
  • Java设计模式之桥接模式
    1.1.概述现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系:我们可以发现有很多的类,假如我们再增加一个形状或再增加一种颜色,就需要创建更多的类。试想,在一个有多种可能会变化的维度的系统中,用继承方式会造成类爆......
  • 日期格式转换异常:Java 8 date/time type `java.time.LocalDateTime` not supported by
    异常信息:"unexpectederror:Typedefinitionerror:[simpletype,classjava.time.LocalDateTime];nestedexceptioniscom.fasterxml.jackson.databind.exc.InvalidDefinitionException:Java8date/timetype`java.time.LocalDateTime`notsupportedbydefault:......