java/poi 调整Excel 列宽支持自适应中文字符宽度

2023-10-27

apache/poi是apache旗下用于读写Microsoft Office 二进制文件和OOXML 格式文件的开源库。用它来进行excel文件的导出是很趁手的。
一般来说可以直接使用 Sheet.autoSizeColumn方法自动调整每列的宽度。但是遇到包含中文的列,autoSizeColumn方法计算的列宽是不正确的,算出的宽度不能完整显示中文内容。最近项目中就遇到了这个问题,于是参考网上的各类文章,自己实现了自动适应中文字符宽度的方法

代码如下:

	/**
	 * 自动调整列表宽度适应中文字符串
	 * @param sheet
	 * @param startColumnNum 要调整的起始列表号
	 * @param size  要调整的列表数量
	 */
	public static void autoColumnWidthForChineseChar(Sheet sheet, int startColumnNum, int size) {    
	    for (int columnNum = 0; columnNum < size; columnNum++) {
	    	/** 调整每一列宽度 */ 
			sheet.autoSizeColumn(columnNum);
	        /** 获取列宽 */
	        final int columnWidth = sheet.getColumnWidth(columnNum);
	        if(columnNum >= 256*256 ){
	        	/** 列宽已经超过最大列宽则放弃当前列遍历 */
	        	continue;
	        }
	        /** 新的列宽 */
	        int newWidth = columnWidth;
	        /** 遍历所有的行,查找有汉字的列计算新的最大列宽 */
	        for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
	            Row currentRow;
	            if (sheet.getRow(rowNum) == null) {
	                continue;
	            } else {
	                currentRow = sheet.getRow(rowNum);
	            }
	            if (currentRow.getCell(columnNum) != null) {
	                Cell currentCell = currentRow.getCell(columnNum);
	                if (currentCell.getCellType() == CellType.STRING) {
	                	String value = currentCell.getStringCellValue();
	                	/** 计算字符串中中文字符的数量 */
	                    int count = chineseCharCountOf(value);
	                    /**在该列字符长度的基础上加上汉字个数计算列宽 */
	                    int length = value.length()*256+count*256*2;
	                	/** 使用字符串的字节长度计算列宽 */
//	                    int length = value.getBytes().length*256;
	                    if (newWidth < length && length < 256*256) {
	                    	newWidth = length;
	                    }
	                }
	            }
	        }
	        if(newWidth != columnWidth){
	        	//设置列宽
	        	sheet.setColumnWidth(columnNum, newWidth);
	        }
	    }
	}
	/**
	 * 计算字符串中中文字符的数量
	 * 参见 <a hrft="https://www.cnblogs.com/straybirds/p/6392306.html">《汉字unicode编码范围》</a>
	 * @param input
	 * @return
	 */
	private static int chineseCharCountOf(String input){
		int count = 0;//汉字数量
		if(null != input){
			String regEx = "[\\u4e00-\\u9fa5]";
			Pattern p = Pattern.compile(regEx);
			Matcher m = p.matcher(input);
			int len = m.groupCount();
			//获取汉字个数
			while (m.find()) {
				for (int i = 0; i <= len; i++) {
					count = count + 1;
				}
			}
		}
		return count;
	}

说明

  • 上面的代码中计算汉字数量的方法chineseCharCountOf,为简化实现只统计编译范围在4e00-u9fa5的2万多汉字,这也是主要使用的汉字,实际汉字unicode编译的范围并不止这一个,参见 《汉字unicode编码范围》,如果更严谨的话,可以把这个方法再完善,将所有的编译范围都包括进去。

  • 在网还找到另一个实现就是直接用使用字符串的字节长度计算列宽,不需要统计汉字个数,实际测试效果也是一样的。

    	/** 使用字符串的字节长度计算列宽 */
        int length = value.getBytes().length*256;

参考资料
《POI Excel 中文自适用宽度》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java/poi 调整Excel 列宽支持自适应中文字符宽度 的相关文章

随机推荐

  • EF Core 7.0 使用教程 (VSCode命令)

    第一步 安装EF Core 安装指令 dotnet tool install global dotnet ef 卸载指令 dotnet tool uninstall global dotnet ef 不可以重复安装 会出现问题 我这里是日语
  • 用ChatGPT 处理复杂 Excel 数据并进行数据分析

    用ChatGPT 处理复杂 Excel 数据的方法 由于目前 ChatGPT 还不支持上传文件以及对大数据量的处理 所以我们只能换一种思路结合 Excel 和 ChatGPT 的协作 整体思路 我们告诉 ChatGTP 我们想要实现什么样的
  • linux:通过端口查对应的服务/应用的位置

    1 根据端口查看对应的进程 lsof i port 2 根据进程号PID查看对应的应用 ps axu grep PID 3 根据应用名称查所在位置 find name 应用名称 4 根据进程号PID查看对应的端口 netstat anp g
  • c盘中可以删除的文件有哪些?

    win7系统很占用空间 所以说 如果你的c盘空间不够强大的话 是无法承载win7系统的 但是即便是安装了win7系统 我们也可以对c盘的空间进行优化 下面小编就来告诉大家 c盘中可以删除的文件有哪些 打开c盘 我们可以看到里面的组织构架 里
  • GW1NSR-LV4CQN48GC6/I5 FPGA呼吸灯

    环境 pwm v cat pwm v module Pwm input clk input 31 0 period input 31 0 duty output pwmout reg 31 0 counter reg r pwmout al
  • iframe+ajaxSubmit结合--续篇(判断图片(文件)大小,上传图片,验证码刷新)

    人们似乎慢慢遗忘了iframe 毕竟在ajax未诞生前 都是用iframe来实现无刷新的效果 当请教iframe实现无刷新知识时 他们说从来没用过 iframe是什么 无奈 只有自己摸索 毕竟我属入门级别 下面的方法从效率上好不好 我也说不
  • 傻瓜式学习webpack(五)——css的抽离和html的自动引入js/css

    一 以前面四篇文章为基础 我们接下来利用webpack进行css的抽离 这里需要安装一个插件 在安装之前 首先要说明一下 如果没有第四篇文章为前提 也就是图片没有进行处理的话 在抽离css的时候 它将无法解析css中的url 所以在抽离之前
  • Linux svn server 给指定文件夹设置相应的读写权限

    简介 在使用Linux搭建SVN服务器的时候 需要给仓库中不同的文件夹设置不同的权限 1 在svn目录中有Dan和Mango两个文件夹 2 进入svn conf目录下 使用vim命令 vi authz配置的authz权限 3 输入相应的指令
  • 第七课旋转物体

    类似于平移 在内容编辑器中的transform rotation更改即可 这样精确
  • JWT 创建Token 提示:secret key byte array cannot be null or empty.

    使用JWT生成Token提示 java lang IllegalArgumentException secret key byte array cannot be null or empty 详细错误信息 java lang Illegal
  • Java面试题(十九个模块)面试必备

    关注我 带了熟悉Java趣事 Java进阶攻略等着你 本文分为十九个模块 分别是 Java 基础 容器 多线程 反射 对象拷贝 Java Web 异常 网络 设计模式 Spring Spring MVC Spring Boot Spring
  • Batch Gradient Descent(python)

    import numpy as np import tensorflow as tf def GradientDescent x y theta m n x shape m is training example while n is fe
  • 金蝶牵手IBM也许是个灾难

    从去年6月开始金蝶 用友与微软 IBM SAP ORACLE 等等陷入了n方收购传闻 前几天终于有了消息 金蝶接受ibm与雷曼兄弟的投资 因本人对金蝶和用友的公司与产品比较的熟悉 所以我认为对金蝶也许不是一件好事 大家都知道ibm的核心是j
  • 关于APP弱网测试

    一 网络测试的一般流程 step1 首先要考虑网络正常的情况 各个模块的功能正常可用 页面元素 数据显示正常 step2 其次要考虑无网络的情况 APP各个功能在无网络情况下是否可用 APP各个页面之间切换是否正常 发送网络请求时是否会导致
  • Base64 —— 编码/解码

    Base64是基于64个字符来表示二进制数据的方法 由于2的6次方等于64 所以每6位为一个字符 对应某个字符 在Base64中的表示字符包括A Z a z 0 9 这样共有62个字符 从左往右依次代表0 61 剩下两个字符 代表62 代表
  • 做期货的阶段(做期货的几个阶段)

    如何自己做好期货 学习交易大致有三阶段 直观直觉阶段 看到涨就做多 看到跌就做空 结果半赢半输 学习积累的阶段 看到涨跌不觉涨跌 想得很多 结果赢少赔多 领悟后再次直观直觉的阶段 看到涨还是涨于是做多 看到跌还是跌于是做空 终于赢比输多 这
  • ae在哪里直接复制合成_AE如何复制同一合成下图层的效果到另一个图层上

    如何把一个图层的动画 效果等属性 比如缩放位移动画 模糊 斜面阴影 径向擦除等 复制到同一合成下的另一个图层上呢 1 合成里面有一个素材01和素材02 素材01上面有效果控件和缩放位移动画 而02上面没有任何效果和动画 现在想把01里面的效
  • Linux 内核编译报错及解决办法记录

    Linux 内核编译报错及解决办法记录 Can t use defined array Maybe you should just omit the defined at kernel timeconst pl line 373 根据错误的
  • UCGUI做汉字显示

    1 弄个包含中文的字体 在这里我借用大多数例子里的 C windows Font simhei ttf 文件 把这个文件拷贝到Datafiles文件夹的Font文件夹里 2 随便照着一个 Font文件 自己写一个simhei font文件
  • java/poi 调整Excel 列宽支持自适应中文字符宽度

    apache poi是apache旗下用于读写Microsoft Office 二进制文件和OOXML 格式文件的开源库 用它来进行excel文件的导出是很趁手的 一般来说可以直接使用 Sheet autoSizeColumn方法自动调整每