问题

  目的是要将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代码库》里介绍

原创文章,欢迎转载,转载请注明出处!

POI如何自动调整Excel单元格中字体的大小的更多相关文章

  1. 如何在excel单元格中插入图片批注

    在excel单元格中插入图片批注的方法: 1.选定要插入图片的单元格,然后右键选择插入批注. 2.然后会插入一个批注框,为了不影响图片效果,可以将批注文字都删除.然后鼠标移动到批注框边角再右键. 3. ...

  2. Java 在Excel单元格中应用一种/多种字体样式

    在Excel表格中,设置单元格字体样式时,可以对单元格内的所有字符应用同一样式,即获取指定单元,应用样式即可:另外也可以对单元格内的不同字符内容应用不同字体样式,即获取单元格中的字符位置,应用样式:本 ...

  3. C#/VB.NET 在Excel单元格中应用多种字体格式

    在Excel中,可对单元格中的字符串设置多种不同样式,通常只需要获取到单元格直接设置样式即可,该方法设置的样式会应用于该单元格中的所有字符.如果需要对单元格中某些字符设置样式,则可以参考本文中的方法. ...

  4. excel单元格中批量加入固定字符

    excel单元格前怎么批量加字母 现在我要在联系人这列,每个姓名前加入衡阳的首字母简写(HY). 3 在同行上面随便找列,我找D列.输入公式:="HY"&A2. 5 输入后 ...

  5. 通过VBA,当在EXCEL单元格中输入任意的日期格式时,都能自动转换为指定的标准格式的日期值

    在日常录入EXCEL表格的单元格里 ,我们输入一些一般性的日期内容,如:2017-10-17 或 2017/10/17时,EXCEL会自动识别为日期并按单元格设计格式显示,单元格中存储的值也是日期格式 ...

  6. POI获取excel单元格红色字体,淡蓝色前景色的内容

    如果是Microsoft Excel 97-2003 工作表 (.xls) if(31 == cell.getCellStyle().getFillForegroundColor()) //判断单元格 ...

  7. 使用Excel对象模型在Excel单元格中设置不同的字体

    效果是这样的: 首先找到这个单元格或区域Range cell,然后代码: ((Range)cell). Characters[, ].Font.Color = Color.Blue; ((Range) ...

  8. POI HSSFCellStyle 设置 Excel 单元格样式

    POI中可能会用到一些需要设置EXCEL单元格格式的操作小结: 先获取工作薄对象: HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb ...

  9. 在excel单元格中提取信息

    平时在excel中处理数据的时候,肯定会遇到在单元格提取信息的情况,比如在地址中提取省.市.地区等,如果数据源内容规整的话,可以直接使用left().right().mid()等函数直接提取,但是大多 ...

随机推荐

  1. Linux常见问题汇总

    Linux问题: ifconfig查看IP地下载报错:bash: ifconfig: commandnotfound 解决方法: 先执行 export PATH="$PATH:/sbin&q ...

  2. 前端自动化 shell 脚本命令 与 shell-node 脚本命令 简单使用 之 es6 转译

    (背景: 先用 babel 转译 es6 再 用 browserify 打包 模块化文件,来解决浏览器不支持模块化 )(Browserify是一个让node模块可以用在浏览器中的神奇工具) 今天折腾了 ...

  3. matplotlib 入门之Sample plots in Matplotlib

    文章目录 Line Plot One figure, a set of subplots Image 展示图片 展示二元正态分布 A sample image Interpolating images ...

  4. Python-类的特性(property)

    什么是特性property property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个 ...

  5. 2018 Multi-University Training Contest 2

    题目链接:2018 Multi-University Training Contest 2 6318 Swaps and Inversions 题意:sum=x*逆序个数+交换次数*y,使sum最小 ...

  6. 实验楼----PHP大法

    地址:http://www.shiyanbar.com/ctf/2008 题目:http://ctf5.shiyanbar.com/DUTCTF/index.php

  7. asp.net core2.0中异常的处理

    最近在开发中遇到一些关于如何抛出异常的困惑,在qq群里进行了讨论,有些人认为抛出异常是有理由的,可以对业务流程进行控制,而有些认为抛出异常会导致程序性能低下,我写一些自己的心得吧. 异常的全局处理 a ...

  8. python学习笔记(11)--数据组织的维度

    数据的操作周期 存储  -- 表示 -- 操作 一维数据表示 如果数据有序,可以使用列表[]:如果数据没有顺序,可以使用集合{} 一维数组存储 存储方式一:空格分隔 ,使用一个或多个空格分隔进行分隔, ...

  9. jenkins插件findbugs+pmd+checkstyle结合sonar与maven(java环境代码质量和代码规范管理)

    一.下载jdk并安装(最好jdk官网下载解压安装的) 二.下载maven并安装maven 三.安装jenkins及插件 安装checkstyle.pmd.findbugs.maven.sonar等相关 ...

  10. vue ajax

    局部get: this.$http.get(url,{param:jsonData}).then(successCallback,failCallBack) 局部post: this.$http.po ...