【问题标题】:Apache poi "pull down" formattingApache poi“下拉”格式
【发布时间】:2020-06-25 07:28:47
【问题描述】:

我要求 apache poi 在 excel 中表现得像“下拉”格式。因此,取一个样本行,获取每个单元格中的“格式”并将其应用于下面的所有单元格。根据要求的格式包括数字格式和单元格的背景颜色根据值变化。所以我写了一个类,它从示例行的单元格中获取CellStyle 并根据它应用它。

public class FormatScheme implements ObjIntConsumer<Sheet> {

    private Map<Integer, CellStyle> cellFormats = new LinkedHashMap<>();

    public static FormatScheme of(Row row, int xOffset){
        FormatScheme scheme = new FormatScheme();

        for (int i = xOffset; i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if(cell==null) continue;

            scheme.cellFormats.put(i, cell.getCellStyle());
        }

        return scheme;
    }


    @Override
    public void accept(Sheet sheet, int rowIndex) {
        Row row = sheet.getRow(rowIndex);
        if(row==null) row=sheet.createRow(rowIndex);
        Row finalRow = row;

        cellFormats.entrySet().forEach(entry -> {
            Cell cell = finalRow.getCell(entry.getKey());
            if(cell==null) cell= finalRow.createCell(entry.getKey());

            cell.setCellStyle(entry.getValue());
        });
    }


    private FormatScheme(){}
}

这似乎适用于数字格式,但不能抓住不断变化的背景颜色。 〜我想,我错过了一些东西。〜

在 Alex Richter 的帮助下,我了解到我需要使用工作表的 SheetConditionalFormatting。如何获取当前应用于单元格的ConditionalFormatting 并向下扩展影响范围?

【问题讨论】:

  • 普通背景颜色是CellStyle 的一部分。但是“单元格的背景颜色会根据值而变化”听起来像是条件格式。这是完全不同的事情,它不存储在单元格中,而是存储在工作表中。新行中的单元格必须插入到工作表的条件格式规则中。见poi.apache.org/components/spreadsheet/…
  • 谢谢你。如何获取当前应用于某个单元格的条件格式?
  • 这是您现在的问题吗?如果是这样,那么请将该问题作为一个问题提出,而不是在对完全不同的问题的评论中提出。

标签: java apache-poi


【解决方案1】:

你的问题不是很清楚。但我怀疑您想将格式从一个目标行复制到多个相邻的后续行。并且您还希望扩展条件格式规则的范围,以便随后相邻行中的单元格也遵循该规则。同样Excel的格式刷选择一行,然后单击格式刷,然后选择多个相邻的后续行。

如何复制单元格样式,你已经掌握了。但是为什么要这么复杂呢?将单元格样式从一个单元格复制到另一个单元格是单行:targetCell.setCellStyle(sourceCell.getCellStyle());

其次,我们也应该复制可能的行样式。以下示例为此提供了一个方法 void copyRowStyle(Row sourceRow, Row targetRow)

要扩展条件格式规则的范围,我们需要获取应用于单元格的规则。规则存储在工作表级别。所以我们需要遍历SheetConditionalFormatting来获取单元格在范围内的规则。以下示例为此提供了一个方法 List&lt;ConditionalFormatting&gt; getConditionalFormattingsForCell(Cell cell)

有了这个,我们可以扩展条件格式规则的范围。以下示例为此提供了一个方法 void expandConditionalFormatting(Cell sourceCell, Cell targetCell)。它将条件格式规则的范围从sourceCell扩展到targetCell

显示原理的完整示例:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.ConditionalFormatting;
import org.apache.poi.ss.util.*;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
 
import java.util.List;
import java.util.ArrayList;
 
class ExcelCopyFormatting {
 
 static List<ConditionalFormatting> getConditionalFormattingsForCell(Cell cell) {
  List<ConditionalFormatting> conditionalFormattingList = new ArrayList<ConditionalFormatting>();
  Sheet sheet = cell.getRow().getSheet();
  SheetConditionalFormatting sheetConditionalFormatting = sheet.getSheetConditionalFormatting();
  for (int i = 0; i < sheetConditionalFormatting.getNumConditionalFormattings(); i++) {
   ConditionalFormatting conditionalFormatting = sheetConditionalFormatting.getConditionalFormattingAt(i);
   CellRangeAddress[] cellRangeAddressArray = conditionalFormatting.getFormattingRanges();
   for (CellRangeAddress cellRangeAddress : cellRangeAddressArray) {
    if (cellRangeAddress.isInRange(cell)) {
     conditionalFormattingList.add(conditionalFormatting);
    }
   }
  }
  return conditionalFormattingList;
 }
 
 static void expandConditionalFormatting(Cell sourceCell, Cell targetCell) {
  List<ConditionalFormatting> conditionalFormattingList = getConditionalFormattingsForCell(sourceCell);
  for (ConditionalFormatting conditionalFormatting : conditionalFormattingList) {
   CellRangeAddress[] cellRangeAddressArray = conditionalFormatting.getFormattingRanges();
   for (int i = 0; i < cellRangeAddressArray.length; i++) {
    CellRangeAddress cellRangeAddress = cellRangeAddressArray[i];
    if (cellRangeAddress.isInRange(sourceCell)) {
     if (cellRangeAddress.getFirstRow() > targetCell.getRowIndex()) {
      cellRangeAddress.setFirstRow(targetCell.getRowIndex());
     }
     if (cellRangeAddress.getFirstColumn() > targetCell.getColumnIndex()) {
      cellRangeAddress.setFirstColumn(targetCell.getColumnIndex());
     }
     if (cellRangeAddress.getLastRow() < targetCell.getRowIndex()) {
      cellRangeAddress.setLastRow(targetCell.getRowIndex());
     }
     if (cellRangeAddress.getLastColumn() < targetCell.getColumnIndex()) {
      cellRangeAddress.setLastColumn(targetCell.getColumnIndex());
     }
     cellRangeAddressArray[i] = cellRangeAddress;
    }
   }
   conditionalFormatting.setFormattingRanges(cellRangeAddressArray);
  }
 }
 
 static void copyRowStyle(Row sourceRow, Row targetRow) {
  if (sourceRow.isFormatted()) {
   targetRow.setRowStyle(sourceRow.getRowStyle());
  }
 }

 static void copyCellStyle(Cell sourceCell, Cell targetCell) {
  targetCell.setCellStyle(sourceCell.getCellStyle());
 }

 static void copyFormatting(Sheet sheet, int fromRow, int upToRow) {
  Row sourceRow = sheet.getRow(fromRow);
  for (int r = fromRow + 1; r <= upToRow; r++) {
   Row targetRow = sheet.getRow(r);
   if (targetRow == null) targetRow = sheet.createRow(r); 
   copyRowStyle(sourceRow, targetRow);
   for (Cell sourceCell : sourceRow) {
    Cell targetCell = targetRow.getCell(sourceCell.getColumnIndex());
    if (targetCell == null) targetCell = targetRow.createCell(sourceCell.getColumnIndex());
    copyCellStyle(sourceCell, targetCell);
    if (r == upToRow) {
     if (getConditionalFormattingsForCell(sourceCell).size() > 0) {
      expandConditionalFormatting(sourceCell, targetCell);
     }
    }
   }
  }
 }
 
 public static void main(String[] args) throws Exception {
  //Workbook workbook = WorkbookFactory.create(new FileInputStream("./Workbook.xls")); String filePath = "./WorkbookNew.xls";
  Workbook workbook = WorkbookFactory.create(new FileInputStream("./Workbook.xlsx")); String filePath = "./WorkbookNew.xlsx";
 
  Sheet sheet = workbook.getSheetAt(0);
 
  copyFormatting(sheet, 1, 9); // copy formatting from row 2 up to row 10
 
  FileOutputStream out = new FileOutputStream(filePath);
  workbook.write(out);
  out.close();
  workbook.close();
 }
}

【讨论】:

    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多