设为首页 收藏本站
查看: 2381|回复: 0

[经验分享] 使用Apache POI精确设置Excel的行高和列宽

[复制链接]

尚未签到

发表于 2017-1-14 10:38:35 | 显示全部楼层 |阅读模式
EXCEL的行高度和列宽度单位是不一样的。
1,EXCEL列高度的单位是磅,Apache POI的行高度单位是缇(twip):
1英寸=72磅=25.4毫米=1440缇
1磅=0.353毫米=20缇

POI中的行高=Excel的行高度*20
Excel的行高度=POI中的行高/20
 
这里顺便把像素的换行方法说一下:
DPI = 1英寸内可显示的像素点个数。通常电脑屏幕是96DPI, IPhone4s的屏幕是326DPI, 普通激光黑白打印机是400DPI
要计算POI行高或者Excel的行高,就先把它行转换到英寸,再乘小DPI就可以得到像素
像素 = (磅/72)*DPI
像素= (Excel的行高度/72)*DPI
像素= (POI中的行高/20/72)*DPI
Excel的行高度=像素/DPI*72
POI中的行高=像素/DPI*72*20
例如在电脑屏幕上, Excel默认行高度为13.5,  (13.5/72)*96=18像素,而Excel中也确实显示的就是18像素。
 
2,EXCEL列宽度的单位是字符个数
(2014-08-18备注:关于Excel的宽度计算的详细介绍在这篇文章Excel的宽度怎么算的?)
在excel2003以上的版本中,可以建立一个空白的xls文档并将第一列宽度拉到10。然后在A1单元格中输入1234567890可以看到单元格正好可以容纳这十个字符。一个字符的宽度是通过测量1234567890这十个字符在默认字体(通常是宋体11号字,视版本可能不同)下的平均宽度得到的。
只要记住一个字符的宽度是8像素 (2013-10-29备注:一个字符的宽度取决于Excel文件中的第一个字体大小,并不一定就是8像素)就可以了。
一个单元格实际的像素宽度还要在 (字符个数 * 默认字符的宽度)的基础上前后各加2个像素的空白边。另外字符之间会叠加一个像素,在计算时也要减去:
(2013-10-29备注:一个字符的边距不一定只是2像素,和字体有关系)
像素 = 2个像素空白 + (字符个数 * 默认字符的宽度) + 2个像素空白 - (字符个数 - 1)
整理一下,公式变成:
像素 = 5 + (字符个数 * (默认字符的宽度 - 1))
代入默认字符宽度8:
像素 = 5 + (字符个数 * 7)
 
POI中的字符宽度算法是:
double 宽度 = (字符个数 * (字符宽度 - 1) + 5) / (字符宽度 - 1) * 256;
然后再四舍五入成整数。
 
最后把我写的一个工具类贴上来,方便使用。
[java] view plaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.csdn.net/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.csdn.net/assets/ico_fork.svg 



  • public class HSSFUtil {  
  •     private static final short TWIPS_PER_PIEXL = 15//1 Pixel = 1440 TPI / 96 DPI = 15 Twips  
  •       
  •     public static short pixel2PoiHeight(int pixel) {  
  •         return (short) (pixel * TWIPS_PER_PIEXL);  
  •     }  
  •   
  •     public static int poiHeight2Pixel(short height) {  
  •         return height / TWIPS_PER_PIEXL;  
  •     }  
  •   
  •     //像素转poi宽度  
  •     public static int pixel2PoiWidth(FontInfo fontInfo, int pixel) {  
  •         double numChars = pixel2Character(fontInfo, pixel);  
  •         numChars *= fontInfo.charWidth;  
  •         numChars += fontInfo.spacing;  
  •         numChars /= fontInfo.charWidth;  
  •         numChars *= 256;  
  •         return (int)numChars;  
  •     }  
  •       
  •     //poi宽度转像素  
  •     public static int poiWidth2Pixel(FontInfo fontInfo, int poiWidth) {  
  •         double numChars = poiWidth2Character(fontInfo, poiWidth);  
  •         return character2Piexl(fontInfo, numChars);  
  •     }  
  •       
  •     public static double poiWidth2Character(FontInfo fontInfo, int poiWidth){  
  •         double numChars = poiWidth / 256.0 - (fontInfo.spacing * 1.0 / fontInfo.charWidth);  
  •         //2位小数  
  •         return new BigDecimal(numChars).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
  •     }  
  •       
  •     public static int character2PoiWidth(FontInfo fontInfo, double numChars){  
  •         double w = (numChars + (fontInfo.spacing * 1.0 / fontInfo.charWidth)) * 256;  
  •         return (int) w;  
  •     }  
  •       
  •     //excel字符转像素  
  •     public static int character2Piexl(FontInfo fontInfo, double numChars){  
  •         double pixel = fontInfo.charWidth * numChars + fontInfo.spacing;  
  •         return (int)pixel;  
  •     }  
  •       
  •     //excel像素转字符  
  •     public static double pixel2Character(FontInfo fontInfo, int pixel){  
  •         double numChars =  (pixel - fontInfo.spacing) * 1.0 / fontInfo.charWidth;  
  •         return new BigDecimal(numChars).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
  •     }  
  •       
  •     //获得工作簿默认字符宽度  
  •     public static FontInfo getDefaultCharWidth(Workbook book){  
  •         //博客没人气,我已删除此段代码,请自行研究或者留邮箱  
  •     }  
  •       
  •     //获得不同字体的字符边距   
  •     private static int getSpacing(int fontHeightInPoints, int charWidth){  
  •         //博客没人气,我已删除此段代码,请自行研究或者留邮箱  
  •     }  
  • }  

 
2014-11-04:宽度的算法在这:《Excel的宽度怎么算的?》点击打开链接

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-328258-1-1.html 上篇帖子: 如何在Spring 3 MVC整合Apache CXF开发Webservice服务 下篇帖子: [web服务器配置]Windows2000下Apache(阿帕奇)web服务器配置全攻略
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表