【问题标题】:Merging Cells Vertically and Inserting Data Into The Cell垂直合并单元格并将数据插入单元格
【发布时间】:2019-01-29 13:42:44
【问题描述】:

我的问题是我有 4 个值。我需要在一个单元格中表示它们。

我需要垂直合并单元格(列)并将四个值呈现在另一个下方(从上到下),在合并的单元格之间有换行符。

我能够垂直合并单元格,但无法在单个单元格中显示四个值。

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

【问题讨论】:

  • 使用 & 或连接将它们连接在一起...
  • 感谢太阳能迈克的回复。你能详细说明一下吗?如果我使用正常连接,我会在单元格中的一行中获得四个值,但我希望它们在备用行中逐一排序
  • 如果您想在一个单元格中但在单独的行中包含 4 个值,那么您需要输入“硬”返回...
  • “不知道如何在评论中附加屏幕截图”:不是在评论中,而是在问题中。但现在很清楚了。所以不需要屏幕截图。
  • 太阳能你能解释一下硬退货吗。带代码示例

标签: java excel apache-poi


【解决方案1】:

合并的单元格区域将它们定向到该区域中的第一个单元格。这意味着单元格样式以及单元格值。所以首先需要设置第一个单元格的单元格样式来换行。然后我们需要将所有单元格值连接到第一个单元格的单元格值中,该单元格值由换行符“\n”分隔。然后我们可以合并单元格。

例子:

SAMPLE.xlsx:

代码:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.util.LocaleUtil;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Locale;

class ExcelConcatenateAndMerge {

 private static void concatenateAndMerge(
  Sheet sheet, CellRangeAddress cellRangeAddress, DataFormatter formatter, FormulaEvaluator evaluator, CellStyle cellStyle) {

  Row row = null;
  Cell cell = null;
  Cell firstCell = null;
  String cellValue = "";
  boolean first = true;
  for (CellAddress cellAddress : cellRangeAddress) {
   row = sheet.getRow(cellAddress.getRow());
   if (first) {
    if (row == null) row = sheet.createRow(cellAddress.getRow());
    firstCell = row.getCell(cellAddress.getColumn());
    if (firstCell == null) firstCell = row.createCell(cellAddress.getColumn());
    firstCell.setCellStyle(cellStyle);
    cellValue = formatter.formatCellValue(firstCell, evaluator);
    first = false;
   } else {
    if (row != null) {
     cell = row.getCell(cellAddress.getColumn());
     if (cell != null) {
      cellValue += "\n" + formatter.formatCellValue(cell, evaluator);
     } else cellValue += "\n" + "";
    } else cellValue += "\n" + "";
   }
  }

  firstCell.setCellValue(cellValue);

  sheet.addMergedRegion(cellRangeAddress);

 }

 public static void main(String[] args) throws Exception {

  Workbook wb  = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));

  Locale locale = new Locale("en", "US");
  LocaleUtil.setUserLocale(locale);
  DataFormatter formatter = new DataFormatter();
  FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  CellStyle cellStyle = wb.createCellStyle();
  cellStyle.setWrapText(true);

  Sheet sheet = wb.getSheetAt(0);
  CellRangeAddress cellRangeAddress = new CellRangeAddress(2,5,5,5);

  concatenateAndMerge(sheet, cellRangeAddress, formatter, evaluator, cellStyle);

  FileOutputStream out = new FileOutputStream("SAMPLENEW.xlsx");
  wb.write(out);
  out.close();
  wb.close();

 }
}

SAMPLENEW.xlsx:

我的方法concatenateAndMerge 使用DataFormatter,因为源单元格内容可能不仅仅是文本,而是日期或其他数字。由于合并的单元格内容需要是串联字符串,因此之前单个单元格的不同内容应该出现在该串联字符串中,如之前在单个单元格中所示。这就是DataFormatter 的原因。我的方法使用FormulaEvaluator,因为源单元格内容也可能包含公式。

【讨论】:

  • 非常感谢 Axel Richter 的回答。我的问题已解决,但请您解释一下为什么在我们的代码中使用 DataFormatter、FormulaEvaluator 以及如何自动调整列的大小
  • @veera venkatesh:在答案中查看我的补充。但是“如何自动调整列的大小”?哪些列应自动调整大小?那么简单地使用Sheet.autoSizeColumn呢?
  • ok Axel。我通过查看您提供的链接来解决我的问题,默认情况下,Autosizecolumn 忽略 MergeCells。我们需要为方法 sheet.autosizeColumn(columnIndex,true) 传递 true 参数。
【解决方案2】:

如果直接在 excel 中使用 VBA 是一种可行的替代方案,您可以编写一个宏来完成此任务。宏将保存在实际的 excel 文件中。

当 Excel 合并单元格时,它只保留第一个单元格的值,因此在合并这些单元格之前,请以所需格式连接它们的值。要为您的值添加换行符,请将 Chr(10) 连接到您想要换行的位置。

请记住,如果您以这种方式格式化数字单元格,单元格值将变为字符串,因此不能再用作公式中的数字。

下面的代码会做你想做的事*:

Dim finalValue As String
For Each c In Selection
    finalValue = finalValue & IIf((Len(finalValue) > 0) And (Len(c.Text) > 0), Chr(10), Empty) & c.Text
Next c

Selection.Clear
Selection.Merge
Selection.Value = finalValue

*注意:我选择了代码,以防您需要对可变单元格编号执行此任务,但它适用于任何 Range 对象

还请注意,除非您删除 IIf 中的 And (Len(c.Text) > 0) 条件,否则空单元格不会产生空行。但是通过这样做,将选择与已合并的单元格合并将创建与[the size of the merged cell] - 1一样多的空行@

【讨论】:

  • 为什么你认为这个问题与VBA有关?它被明确标记为javaapache poi
  • If using VBA directly in excel is a viable alternative 答案清楚地表明这里提出的解决方案是一种替代方案。
猜你喜欢
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 2012-01-12
  • 2015-04-27
  • 2019-11-26
  • 1970-01-01
相关资源
最近更新 更多