博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POI如何自动调整Excel单元格中字体的大小
阅读量:5754 次
发布时间:2019-06-18

本文共 3768 字,大约阅读时间需要 12 分钟。

 

HSSFRow row = sheet.createRow((short) 0);HSSFCellStyle style = workbook.createCellStyle();style.setAlignment(HSSFCellStyle.ALIGN_CENTER);HSSFFont font = workbook.createFont(); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);style.setAlignment(HSSFCellStyle.ALIGN_CENTER);font.setFontName("宋体");font.setFontHeightInPoints((short) 14);// 设置字体大小

 

 

问题

  目的是要将Excel中的文字全部显示出来,可以设置对齐格式为【缩小字体填充】,但是这样的话只能展示出一行数据,字体会变得很小。还有一种办法,设置对齐格式为【自动换行】,然后让单元格中的字体自动调整大小。

  我的实现思路是,设置单元格中的字体大小,最大10号字,最小5号字,判断优先使用大的字体;如果最小的5号字也放不下,那就只能调整模板了。关键点就是判断当前字号能否将内容完全展示在单元格中。

  需要提前说明一点,我的这个方法是不精确的算法,excel设置字体的时候太强大了,不同的字体的字间距、行间距都会不同。

 

关键点

  判断字体大小是否合理的思路:

  1、计算出单元格的总宽度、总高度

  2、计算出其中的内容的总长度,不同的字号,长度是不同的
  3、内容总长度除以单元格宽度,得出实际上一共有多少行数据 x 
  4、单元格的总高度除以内字体的高度,得出能展示出来的数据有多少行 y
  5、如果 y>=x ,那么表示所有的数据都能展示出来

  这个判断单元格中的字体大小是否合理的思路也不难,难的是如何获取到需要的参数。

 

注意点

  1、设置单元格字体大小的方法是:font.setFontHeightInPoints(k),但是获取字体宽度和高度的方法并不精确,因为字体间会有字间距,换行以后行之间也有间距,所以这个算法并不精确。

    这个例子中,我的获取字体高度的方法是直接取 k,获取字体宽度的方法是 k*2

  2、在上诉关键点的第5步中,本来我的想法是 y向下取整, x向上取整,然后再进行比较。但是测试后发现,设置的字体都会偏小。 直接取y>=x,结果反而更合理些。

  3、进行相除运算,单位必须相同。POI中Point(坐标点)和Pixel(像素点)的大小关系,我在之前的文章有介绍过,引用结论,获取行高的像素值的方法就是: (row.getHeightInPoints() / 72) * 96

 

代码实例

  样例中的单元格是合并单元格,起始坐标 (3,5),结束坐标 (3,8)

public static void main(String[] args) {    try (InputStream is = new FileInputStream("E:\\test1.xls");         Workbook book = new HSSFWorkbook(is);) {        Cell cell = book.getSheetAt(0).getRow(3).getCell(5);        String str = "一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十";        cell.setCellValue(str);        setFontSize(book, cell);        File f = new File("E:\\test2.xls");        FileOutputStream out = new FileOutputStream(f);        book.write(out);    } catch (IOException e) {        //return;    }}/** * 设置单元格字体大小 */private static void setFontSize(Workbook book, Cell cell) {    Font font = book.createFont();    font.setFontName("EUDC");    for (short k = 10; k >= 5; k--) {        font.setFontHeightInPoints(k);        if (checkCellReasonable(cell, k)) {            break;        }    }    //解决单元格样式覆盖的问题    CellStyle cStyle = book.createCellStyle();    cStyle.cloneStyleFrom(cell.getCellStyle());    cStyle.setWrapText(true);    cStyle.setFont(font);    cell.setCellStyle(cStyle);}/** * 校验单元格中的字体大小是否合理 */private static boolean checkCellReasonable(Cell cell, short fontSize) {    int sum = cell.getStringCellValue().length();    double cellWidth = getTotalWidth(cell);    double fontWidth = (double) fontSize / 72 * 96 * 2;    double cellHeight = cell.getRow().getHeightInPoints();    double rows1 = fontWidth * sum / cellWidth;    double rows2 = cellHeight / fontSize;    return rows2 >= rows1;}/** * 获取单元格的总宽度(单位:像素) */private static double getTotalWidth(Cell cell) {    int x = getColNum(cell.getSheet(), cell.getRowIndex(), cell.getColumnIndex());    double totalWidthInPixels = 0;    for (int i = 0; i < x; i++) {        totalWidthInPixels += cell.getSheet().getColumnWidthInPixels(i + cell.getColumnIndex());    }    return totalWidthInPixels;}/** * 获取单元格的列数,如果是合并单元格,就获取总的列数 */private static int getColNum(Sheet sheet, int row, int column) {    int sheetMergeCount = sheet.getNumMergedRegions();    //判断该单元格是否是合并区域的内容    for (int i = 0; i < sheetMergeCount; i++) {        CellRangeAddress ca = sheet.getMergedRegion(i);        int firstColumn = ca.getFirstColumn();        int lastColumn = ca.getLastColumn();        int firstRow = ca.getFirstRow();        int lastRow = ca.getLastRow();        if (row >= firstRow && row <= lastRow && column >= firstColumn && column <= lastColumn) {            return lastColumn - firstColumn + 1;        }    }    return 1;}

 

  其中,获取单元格总宽度的方法getTotalWidth(Cell cell),有更简单的方法,在《我的POI代码库》里介绍

https://www.cnblogs.com/acm-bingzi/p/poiFontSizeAuto.html

 

转载于:https://www.cnblogs.com/softidea/p/10207194.html

你可能感兴趣的文章
随笔2013/2/19
查看>>
Windows Phone的Silverlight Toolkit 安装及其使用
查看>>
20135203齐岳信息安全系统设计基础——实验一实验报告
查看>>
Asp.net安全架构之4:Brute force(爆破)
查看>>
DBS:同学录
查看>>
Mysql备份系列(1)--备份方案总结性梳理
查看>>
[CareerCup] 1.6 Rotate Image 翻转图像
查看>>
Execution Plan 执行计划介绍
查看>>
Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals)爆零记
查看>>
jQuery中$.fn的用法示例介绍
查看>>
Python中的画图初体验
查看>>
关于前端的photoshop初探的学习笔记
查看>>
Java程序员的日常 —— 响应式导航Demo
查看>>
敏捷软件开发宣言--常读常新
查看>>
objective-c内存管理基础
查看>>
httpServlet,GenericServlet,Servlet源码分析
查看>>
easyUI——datebox验证和自定义取消按钮
查看>>
第 20 章 Nagios
查看>>
JS中的!=、== 、!==、===的用法和区别
查看>>
sap关于价值串的说法(转载)
查看>>