垂直合并单元格并将数据插入单元格

时间:2019-01-29 13:42:44

标签: java excel apache-poi

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

我需要垂直合并这些单元格(列),并在合并后的单元格之间以换行的形式将四个值一个接一个地显示在另一个下(从上至下)。

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

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

2 个答案:

答案 0 :(得分:3)

合并的单元格区域将它们自身定位在该区域中的第一个单元格上。这意味着单元格样式以及单元格值。因此,首先需要设置第一个单元格的单元格样式以包装文本。然后,我们需要将所有单元格值连接在一起,以换行符“ \ n”分隔的第一个单元格的单元格值。然后我们可以合并单元格。

示例:

SAMPLE.xlsx: enter image description here

代码:

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: enter image description here

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

答案 1 :(得分:0)

如果直接在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对象上工作

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

一样多的空行