使用Apache POI精确设置Excel的行高和列宽

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;

然后再四舍五入成整数。

 

最后把我写的一个工具类贴上来,方便使用。

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的宽度怎么算的?》点击打开链接
 

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 50
    评论
使用Apache POI可以通过调用Row的setHeightInPoints()方法和Sheet的setColumnWidth()方法来精确设置Excel行高列宽。 要设置行高,首先需要创建一个Row对象,然后调用setHeightInPoints()方法,传入要设置的高度值。该方法接受以磅为单位的浮点数值,可以使用常见的像素值进行换算。例如,要将行高设置为20像素,可以传入20/0.75的值。 示例代码如下: ``` // 创建工作簿和工作表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Sheet1"); // 创建行并设置行高 Row row = sheet.createRow(0); row.setHeightInPoints(20/0.75f); // 将工作簿写入文件 FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); workbook.close(); ``` 要设置列宽,需要先创建一个Sheet对象,然后调用setColumnWidth()方法,传入要设置索引和度值。度值是以字符度的256倍为单位的,可以根据实际需求进行换算。例如,要将第一设置为10个字符度,可以传入10*256的值。 示例代码如下: ``` // 创建工作簿和工作表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Sheet1"); // 设置列宽 sheet.setColumnWidth(0, 10*256); // 将工作簿写入文件 FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); workbook.close(); ``` 通过调用上述方法,我们可以在使用Apache POI精确设置Excel行高列宽
评论 50
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值