XSSFSheet Apache POI - 是否可以锁定所有内容但允许更新和插入行?

XSSFSheet Apache POI - is it possible to lock everything but allowing update and insert rows?

我尝试锁定整个 sheet 但某些列应该解锁(我想在某些列中添加值)。我想复制一些行,添加新行并粘贴复制行中的值。可能吗?

 public ByteArrayResource getQuestionnaireTemplate(List<QuestionnaireTemplateDto> questionnaireTemplateInitialData) throws IOException {
        XSSFWorkbook workbook = excelExportService.createExcelWorkBook();

        String frameworkName = questionnaireTemplateInitialData.stream().map(QuestionnaireTemplateDto::getFramework).findFirst().orElse("Framework Name");
        XSSFSheet sheet = workbook.createSheet(frameworkName);
//        sheet.lockInsertColumns(true);
//        sheet.lockInsertRows(false);
        sheet.enableLocking();
//        sheet.lo
//        CellStyle unlockedCellStyle = workbook.createCellStyle();
//        unlockedCellStyle.setLocked(false);

        CTSheetProtection sheetProtection = sheet.getCTWorksheet().getSheetProtection();
        sheetProtection.setSelectLockedCells(false);
        sheetProtection.setSelectUnlockedCells(false);
        sheetProtection.setFormatCells(false);
        sheetProtection.setFormatColumns(false);
        sheetProtection.setFormatRows(false);
        sheetProtection.setInsertColumns(false);
        sheetProtection.setInsertRows(false);
        sheetProtection.setInsertHyperlinks(false);
        sheetProtection.setDeleteColumns(false);
        sheetProtection.setDeleteRows(false);
        sheetProtection.setSort(false);
        sheetProtection.setAutoFilter(false);
        sheetProtection.setPivotTables(false);
        sheetProtection.setObjects(false);
        sheetProtection.setScenarios(false);

A​​md 然后我可以将一些单元格设置为可编辑(有效):

  private void addFieldRow(XSSFSheet sheet, XSSFCellStyle fieldRowStyle, QuestionnaireTemplateDto questionnaireTemplateDto) {
        XSSFRow row = excelExportService.createRow(sheet,
                sheet.getLastRowNum() + 1,
                Arrays.asList(questionnaireTemplateDto.getFrameworkFieldId().toString(), questionnaireTemplateDto.getFramework(), questionnaireTemplateDto.getFieldName(), questionnaireTemplateDto.getYear().toString()),
                fieldRowStyle);

        CellStyle unlockedStyle = sheet.getWorkbook().createCellStyle();
        unlockedStyle.setLocked(false);
        XSSFCell cell = row.createCell(4);
        cell.setCellStyle(unlockedStyle);
    }

我生成的 sheet 除了一个小细节外工作完美 - 我无法插入新行并将其他行复制到它...

我想我尝试了 Stack Overflow 中的所有解决方案...

您应该使用 XSSFSheet 方法而不是低级 CTSheetProtection 方法来指定 sheet 保护。在当前 apache poi 4.1.2 中,所有的可能性也可以使用 XSSFSheet.lock...- 方法。

但是你想要的,也不是完全可以的。 Sheet保护主要是保护cells不被改变。因此,如果您允许删除行并且该行包含受保护的单元格,则删除该行会与单元格保护相矛盾。将一行复制到另一行也是如此。如果另一行包含受保护的单元格,则复制也会与单元格保护相矛盾。

下面的完整示例创建了一个包含 sheet 的工作簿,其中除列 ACE 外的所有单元格都受到保护。 sheet 保护允许格式化行、插入行和删除行。但是删除行与该行中除 ACE 列中的所有单元格之外的所有单元格的单元格保护相矛盾。所以删除行是允许的,但不可能。

因此结果 sheet 只允许更改列 ACE 中的单元格、格式化行(行高)和插入行。

import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

public class CreateExcelXSSFProtectedSheet {

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

  Workbook workbook = new XSSFWorkbook();
  CellStyle notLocked = workbook.createCellStyle();
  notLocked.setLocked(false);

  Sheet sheet = workbook.createSheet();

  sheet.setDefaultColumnStyle(0, notLocked); // column A is not locked
  sheet.setDefaultColumnStyle(2, notLocked); // column C is not locked
  sheet.setDefaultColumnStyle(4, notLocked); // column E is not locked

  ((XSSFSheet)sheet).lockFormatRows(false); // formatting rows is allowed
  ((XSSFSheet)sheet).lockInsertRows(false); // inserting rows is allowed
  ((XSSFSheet)sheet).lockDeleteRows(false); // deleting rows is allowed but may contradict cell protection

  sheet.protectSheet("");

  FileOutputStream out = new FileOutputStream("CreateExcelXSSFProtectedSheet.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();

 }

}