Apache POI宽度计算

时间:2014-03-07 20:08:21

标签: apache-poi

我在计算columnWidth和计算的行高时遇到了我想要的确切大小,因为我不懂文档。

就columnWidth而言,我使用的是代码行sheet.setColumnWidth(int columnIndex, int width);,但我不明白如何正确计算宽度。我明白了:

width = Truncate([{Number of Visible Characters} * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256

所以我有一个确切的Excel工作表示例,说明我要创建的内容,当我突出显示一列并选择列宽时,它会告诉我它是9.67 (94 pixels)。那么这是什么意思?如何将其插入到我的等式中以获得我想要的宽度值?

我遇到的另一个问题是我正在使用我在别处找到的代码(甚至在SO上)来动态计算行高。但我的问题是我不明白下面代码中的mergedCellWidth应该在nextPos = measurer.nextOffset(mergedCellWidth)行中。我似乎无法正确地得到这个值,并且它弄乱了它认为应该有多少行,因此我的行高度不对。

java.awt.Font currFont = new java.awt.Font("Calibri", 0, 11);
AttributedString attrStr = new AttributedString(record.getDescription());
attrStr.addAttribute(TextAttribute.FONT, currFont);

// Use LineBreakMeasurer to count number of lines needed for the text
FontRenderContext frc = new FontRenderContext(null, true, true);
LineBreakMeasurer measurer = new LineBreakMeasurer(attrStr.getIterator(), frc);
int nextPos = 0;
int lineCnt = 0;

while (measurer.getPosition() < record.getDescription().length()) {
    System.out.println(measurer.getPosition());
    nextPos = measurer.nextOffset(mergedCellWidth); // mergedCellWidth is the max width of each line
    lineCnt++;
    measurer.setPosition(nextPos);
    System.out.println(measurer.getPosition());
}

row.setHeight((short)(row.getHeight() * lineCnt));

我认为在我的情况下,例子对我来说是最好的答案。谢谢!

2 个答案:

答案 0 :(得分:11)

好吧,似乎没有人真的可以帮助我。经过反复试验,我发现了一些对我有用的近似值。

关于我的sheet.setColumnWidth(int columnIndex, int width);问题,我发现一个很好的近似值如下:

  1. 在Excel中,转到“正常”视图。
  2. 转到格式 - &gt;列宽...并记下值
  3. 使用以下公式计算宽度:width = ([number from step 2] * 256) + 200
  4. 这实际上似乎运作得相当好。

    关于mergedCellWidth应该是什么的第二个问题,我发现以下方法可以正常使用该值:(float) (sheet.getColumnWidth(columnIndex) / 256 * 4)。它对于较小长度的字符串效果更好,随着字符串变大,行开始变得有点太大(所以我假设因子4有点太多但它适用于我的目的)。

    我还检查了自动调整大小列的Apache POI源代码,试图了解正在发生的事情。关于单位的意思并没有很多方向,我无法按照他们的计算并在我的Excel模板中重现它们。

答案 1 :(得分:1)

在Excel 2007中,使用XSSF文件(xlsx),以下代码似乎完美无缺:

public static int poiWidthToPixels(final double widthUnits) {
        if (widthUnits <= 256) {
            return (int) Math.round((widthUnits / 28));
        } else {
            return (int) (Math.round(widthUnits * 9 / 256));
        }
}

其中widthUnits是Sheet.getColumnWidth返回的值。