字数不多,全是干货;
心血凝结,全网唯一;
如有帮助,请您点赞;
未经许可,禁止转载!

申明:本文是个人原创,目前只发表于CSDN平台。

前两年基于Apache POI做了个Excel转Html的程序。为了让HTML中列宽的显示尺寸精确吻合Excel原生显示尺寸,做了大量的研究和试算,不同字号不同字体测试了N多种组合,最终完美还原了Excel列宽像素计算方法。今天有空,为了知识不被遗忘,写个博记录一下,全网独一份哦!

首先,要知道每个Excel文件都有一个缺省字体定义,包含了字体、字号信息。这个缺省字体是在Excel选项中指定的,当新建一个工作簿时就被作为内置属性在文件中固化下来。如下图所示:

该字体的宽度被作为一个基本度量单位用于与列宽相关的计算。POI源码中涉及像素、缺省列宽的计算是大多是错误或者说不完善的,其中最主要的一点就是其对Excel的缺省字体宽度没有正确获取,在3.x版本中(4.x没看过)直接硬编码了一个数字8(好像是)作为字体宽度,且对单元格padding部分的处理不正确,因此后续相关的像素计算都得不到正确结果。我在做Excel转Html的过程中,不得不自行研究计算,最终能生成像素级一致的HTML,效果非常好。

下面开始讲解Excel是如何进行像素计算的。具体来说是这样的:

  • 对Excel来说默认字体有一个缺省宽度,其定义是0-9这10个字符中最宽的字符的像素值。以下,我简称该值为DFW(Default Font Width)。
  • Excel的列宽总是以DFW为单位,而与当前列或单元格中的实际字体无关。当在Excel中设置列宽时,对话框中输入的数字即是DFW的倍数,其含义是该列能显示多少个缺省字体字符。下图是缺省字体为"宋体,48"时缺省列的宽度。

  • 列宽的精确像素值由所能容纳的字符总宽度、两端的空白(padding)和1px的margin(网格线)组成,其中padding是DFW除以4后的向上取整值。整体计算步骤略微复杂,下面通过实例来讲解。

首先,请把Excel的默认字体设置为"宋体,48",然后新建一个文件,查看任意一列的列宽一定为8.22(参见上图)。这个8.22是怎么来的呢,和列的像素宽度有什么关系?敲黑板,Excel是按照下面的步骤计算列宽的:

  1. 48号的宋体,字符宽度是32像素(别问我是怎么知道的,不信你量一下)。Excel默认列宽要求必须完整显示8个字符,所以字符总宽度为8*32=256px;
  2. padding = 向上取整(DFW/4) = 8px,两边总共16px,再加上1px的网格线,现在的宽度=256+16+1=273px。
  3. Excel规定每列的像素宽度必须是8的整数倍(为了在滚动时提高渲染性能),故把273px向上取整为8的整数倍,得到280px,这就是该列最终在屏幕上占据的实际像素宽度,不信拿尺子量。

现在我们已经计算出默认列宽为280像素,再来算一下究竟能显示多少个缺省字符。很简单,去掉第2步中的padding和margin共17px再除以DFW,即(280-17)/32 = 8.22,与Excel中实际看到的完全一致。这就是缺省列宽为8.22的来历。如果给Excel指定不同的默认字体,你会发现缺省列宽无规律地变来变去(但肯定大于8),这都是上述算法造成的结果。

在上述过程中,最核心的数值是DFW。它是怎么得到的呢?换句话说,在Java中如何得到任意一种字体的0-9数字的最大宽度?我试过stackoverflow或apache论坛等各种渠道找到的计算方法,比如用java.awt.font.TextLayout,都无法得到完全准确的结果,有时候正确,有时候会差一两个像素。最终我是用了一个很low很粗暴的方法在有限条件下解决,就是写了个windows小程序通过windows API把系统所有字体所有字号所有格式(下划线、加粗等)循环一遍生成数据集,使用的时候直接查表,系统没有安装的字体就没办法了,只能当成默认字体处理。如果看官有简单准确的办法精确计算字体宽度,请不吝赐教!

Excel列宽像素值计算方法详解相关推荐

  1. dataframe 一列的不同值_pandas | 详解DataFrame中的apply与applymap方法

    点击上方蓝字,关注并星标,和我一起学技术. 今天是pandas数据处理专题的第5篇文章,我们来聊聊pandas的一些高级运算. 在上一篇文章当中,我们介绍了panads的一些计算方法,比如两个data ...

  2. excel2010设置列宽为像素_使用像素单位设置 EXCEL 列宽或行高

    在导出 Excel 的时候, 经常要需要给列设置宽度或给行设置高度, 在使用 NPOI 或 EppPlus 等组件进行操作的时候, 列宽和行高的单位都不是像素, 好像是英寸,具体是啥也说不清. 平常在 ...

  3. python生成表格文件_python 读取excel文件生成sql文件实例详解

    python 读取excel文件生成sql文件实例详解 学了python这么久,总算是在工作中用到一次.这次是为了从excel文件中读取数据然后写入到数据库中.这个逻辑用java来写的话就太重了,所以 ...

  4. java导出excel设置行高列宽_使用POI生成Excel文件,可以自动调整excel列宽

    //autoSizeColumn()方法自动调整excel列宽 importjava.io.FileOutputStream; importorg.apache.poi.hssf.usermodel. ...

  5. python读取遥感 dat_基于python批量处理dat文件及科学计算方法详解

    摘要:主要介绍一些python的文件读取功能,文件内容修改,文件名后缀更改等操作. 批处理文件功能 import os path1 = 'C:\\Users\\awake_ljw\\Documents ...

  6. 使用POI生成Excel文件,可以自动调整excel列宽

    //autoSizeColumn()方法自动调整excel列宽 importjava.io.FileOutputStream;importorg.apache.poi.hssf.usermodel.H ...

  7. (转)C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    原文链接:https://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T ...

  8. php计算股票均线,均线怎么算?均线的计算方法详解

    均线怎么算?均线的计算方法详解 学习股票知识首先需要了解各大技术指标,股票均线是最常用的技术指标,新股民学习股票均线肯定有很多不了解的地方,今天股票知识就给大家讲解一下股票均线是怎么来的? 日均线的计 ...

  9. Pandas读取和将数据存储到多个sheet的excel以及read_excel函数常用参数详解

    Pandas读取和将数据存储到多个sheet的excel以及read_excel函数常用参数详解 Excel数据显示: read_excel函数常用参数详解 1.io 读取路径 个人比较喜欢第一种(r ...

最新文章

  1. 简单的并发测试工具 ab.exe ab.zip可下载 -摘自网络
  2. 工作68:json校验工具
  3. 【转载】世界各地对BI的应用状况
  4. c#调用本地命令并截取Output
  5. C++算法八:快速排序
  6. 腾讯开源围棋AI程序PhoenixGo,复现AlphaGo Zero
  7. tp框架like模糊查询报错
  8. java毕向东练习题,java中的String类的练习(来自毕向东老师视频资料)
  9. 安装Ubuntu详细教程
  10. Feb23 小白《linux就该这么学》学习笔记5
  11. pandas算加权平均值_Pandas数据帧中多列的加权平均数
  12. 逸尘杀菌洗地机2 Pro上手体验
  13. 财务人员的6大数据分析方法
  14. Ubuntu-18.04版本网络配置,连接网络的方法
  15. OpenCV图像处理知识点梳理
  16. libjpeg库和libpng库的移植和使用
  17. 在这里,我们为您绘制了专属海报,请您查收!
  18. 【矩阵论】1. 准备知识——复数域上矩阵,Hermite变换
  19. 《弃子长安》第二章 长乐驱蛊
  20. Paragon Hard Disk Manager 17 Business中文版

热门文章

  1. 2022年最流行的自动化测试工具有哪些?全网最全最细都在这里了
  2. 数据库优化三部曲(2)-读写分离-一蓑烟雨任平生
  3. 基于Vue+JavaScript实现的手机移动端宠物商城系统(附完整源码)
  4. Bazel官方教程 -- 通用C++使用案例
  5. 封神台--第二章:遇到阻难!绕过WAF过滤!解题思路
  6. Web前端基础-CSS美化文档
  7. FGL40N120AN-ASEMI大功率IGBT管40A 1200V
  8. springmvc参数注入源码剖析源码扩展
  9. bim机电建模:快速翻弯,打断,管线连接,排布一键解决!
  10. 嵌入式linux电子设计,基于嵌入式Linux的PMP系统设计与实现