java - 如何使用合并的单元格值大于单元格宽度的 Apache-POI 增加 excel 行的高度?

标签 java algorithm apache-poi

我正在使用 java 类创建一个大型 excel。 Excel 包含一个存储字符串的合并单元格。字符串的长度非常大,我正在动态获取这个字符串。我需要增加合并单元格的高度,以便完整的字符串适合该单元格。我试过使用“换行文本”,它换行文本但不会增加合并单元格的高度,因为在 excel 中看不到完整的字符串。 我正在使用的 Java 类是:

  1. XSSF工作簿
  2. XSSFSheet
  3. XSSFRow
  4. XSSFCell
  5. XSSFCellStype

以及其他需要依赖的类。 有没有办法根据单元格值增加合并单元格的高度。

最佳答案

让您了解如何计算所需行高的挑战。

我们可以使用 Sheet.getColumnWidth(int) 获取列的字符宽度中的列宽.但这并不准确,因为它仅适用于数字字形:1,2,3,4,5,6,7,8,9,0。在 True Type 字体中,有些字形 (., |, l, ...) 需要的宽度要小得多。因此,这个结果将与文本中使用的宽度较小的字形一样不准确。

我们可能会按一个系数更正字符中的列宽。我用 5/4。但这在很大程度上取决于所使用的语言。

然后我们可以计算所需的行数,然后通过获取用于一行的默认行高并将其乘以所需的行数来获得所需的行高。

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;

public class CreateExcelCellWrapText {

 public static void main(String[] args) throws Exception {
  XSSFWorkbook workbook = new XSSFWorkbook();

  CellStyle cellstyle = workbook.createCellStyle();
  cellstyle.setWrapText(true);

  Sheet sheet = workbook.createSheet();

//__________________________not merged = height is auto sized

  Row row = sheet.createRow(0);

  Cell cell = row.createCell(2);
  cell.setCellValue("String cell content\nhaving line wrap.");
  cell.setCellStyle(cellstyle);

//__________________________merged = height is not auto sized

  row = sheet.createRow(2);

  cell = row.createCell(2);
  cell.setCellValue("String cell content\nhaving line wrap.");
  cell.setCellStyle(cellstyle);

  CellRangeAddress cellRangeAddress = new CellRangeAddress(2, 2, 2, 3);
  sheet.addMergedRegion(cellRangeAddress);

//__________________________merged with calculated height

  row = sheet.createRow(4);

  String text = "String cell content\nhaving line wrap.\nIt has new line marks and then a long text without new line marks.\nFollowed by short text part.\n\n\nGreetings";

  cell = row.createCell(2);
  cell.setCellValue(text);
  cell.setCellStyle(cellstyle);

  cellRangeAddress = new CellRangeAddress(4, 4, 2, 3);
  sheet.addMergedRegion(cellRangeAddress);

  //get the column width in character widths for the merged columns
  //this is not really accurate since it only is for number glyphs: 1,2,3,4,5,6,7,8,9,0
  //in true type fonts there are glyps (., |, l, ...) which need much less width
  int colwidthinchars = (sheet.getColumnWidth(2) + sheet.getColumnWidth(3)) / 256;
System.out.println(colwidthinchars);
  //correct the colwidthinchars by a factor 5/4 (highly dependent on the language used)
  colwidthinchars = Math.round(colwidthinchars * 5f/4f);
System.out.println(colwidthinchars);

  //calculate the needed rows dependent on the text and the column width in character widths
  String[] chars = text.split("");
  int neededrows = 1;
  int counter = 0;
  for (int i = 0; i < chars.length; i++) {
   counter++;
   if (counter == colwidthinchars) {
System.out.println("new line because of charcter count");
    neededrows++;
    counter = 0;
   } else if ("\n".equals(chars[i])) {
System.out.println("new line because of new line mark");
    neededrows++;
    counter = 0;
   }
  }

System.out.println(neededrows);

  //get default row height
  float defaultrowheight = sheet.getDefaultRowHeightInPoints();
System.out.println(defaultrowheight);

  row.setHeightInPoints(neededrows * defaultrowheight);

  workbook.write(new FileOutputStream("CreateExcelCellWrapText.xlsx"));
  workbook.close();
 }
}

之所以有效,是因为使用了默认字体和字体大小。当使用不同的字体和不同的字体大小时,挑战会增加到无穷大;-)。

参见 How to get the needed height of a multi line rich-text field (any font, any font size) having defined width using Java?例如,在 JTextPane 中呈现格式化文本以获得首选高度。

关于java - 如何使用合并的单元格值大于单元格宽度的 Apache-POI 增加 excel 行的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45387206/

相关文章:

Java POI api在后台更新excel数据而不关闭excel?

java - 在参数上调用静态方法而不实例化参数中的类

java - junit5如何运行测试文件夹中的所有类?

c# - 从字节数组中获取字节 block 的起始位置

浏览器用于在网页中搜索单词的算法

java - Apache POI 从工作簿中删除 CellStyle

java - JMS MessageProducer.setTimeToLive() 与 TextMessage.setJMSExpiration()

java - Ant 属性覆盖

algorithm - 检查数值约束表达式的允许值的等价性/子集

java - 使用 POI 在 Excel 中拉伸(stretch)图像