You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不调用protectSheet()时设置.xlsx指定行不可编辑?

仅锁定指定行实现不可编辑的可行方案

当然可以实现,核心是利用Excel的工作表保护机制:开启保护后,单元格默认处于锁定不可编辑状态,我们只需要把允许编辑的单元格设置为解锁状态,指定行保持锁定即可。

你的代码问题分析

你当前的逻辑完全搞反了:创建了setLocked(false)的样式却给需要不可编辑的行应用,且未处理其他行的解锁设置,导致达不到预期效果。

修改后的实现步骤

  1. 创建允许编辑的单元格样式,设置setLocked(false)
  2. 给所有需要用户编辑的行/单元格应用这个样式
  3. 开启工作表保护(protectSheet),此时未应用解锁样式的指定行会保持不可编辑
  4. 注意:合并单元格的锁定状态由左上角单元格决定,需确保合并区域的左上角单元格样式正确

修改后的代码片段

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class CmWriteXLSXTemplateFile {

    public static void main(String[] args) {
        XSSFWorkbook wb = new XSSFWorkbook();
        try {
            FileOutputStream fileOut = new FileOutputStream("D:\\Personal\\Practise\\test.xlsx");
            XSSFSheet sheet1 = wb.createSheet("Main_Tab");
            XSSFSheet sheet2 = wb.createSheet("Defination");

            // 创建允许编辑的样式:设置为未锁定
            CellStyle editableStyle = wb.createCellStyle();
            editableStyle.setLocked(false);

            // 创建锁定样式(可选,显式设置更清晰,默认单元格已锁定)
            CellStyle lockedStyle = wb.createCellStyle();
            lockedStyle.setLocked(true);

            // 生成原有内容结构
            ArrayList<String> tt = new ArrayList<>();
            for(int kk=0;kk< 42;kk++){
                tt.add("C"+kk);
            }

            // 第0行:设置为不可编辑
            XSSFRow row0 = sheet1.createRow(0);
            Cell cell0 = row0.createCell(0);
            sheet1.addMergedRegion(new CellRangeAddress(0, 0, 0, 7));
            CellStyle cellStyle0 = wb.createCellStyle();
            cellStyle0.setFillBackgroundColor(IndexedColors.BLUE.getIndex());
            cellStyle0.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle0.setLocked(true); // 显式锁定
            XSSFFont fontBoldItalic = wb.createFont();
            fontBoldItalic.setBold(true);
            fontBoldItalic.setItalic(true);
            XSSFRichTextString cellValue0 = new XSSFRichTextString();
            cellValue0.append("Fixed Columns", fontBoldItalic);
            cell0.setCellValue(cellValue0);
            cell0.setCellStyle(cellStyle0);

            Cell cell0_1 = row0.createCell(8);
            sheet1.addMergedRegion(new CellRangeAddress(0, 0, 8, 28));
            CellStyle cellStyle0_1 = wb.createCellStyle();
            cellStyle0_1.setFillBackgroundColor(IndexedColors.BROWN.index);
            cellStyle0_1.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle0_1.setLocked(true); // 显式锁定
            XSSFFont fontBoldItalic0_1 = wb.createFont();
            fontBoldItalic0_1.setBold(true);
            fontBoldItalic0_1.setItalic(true);
            XSSFRichTextString cellValue0_1 = new XSSFRichTextString();
            cellValue0_1.append("Dynamics Columns", fontBoldItalic0_1);
            cell0_1.setCellValue(cellValue0_1);
            cell0_1.setCellStyle(cellStyle0_1);

            // 第1行:设置为不可编辑
            Row row1 = sheet1.createRow(1);
            Cell cell12 = row1.createCell(0);
            sheet1.addMergedRegion(new CellRangeAddress(1, 1, 0, 1));
            CellStyle cellStyle12 = wb.createCellStyle();
            cellStyle12.setFillBackgroundColor(IndexedColors.BROWN.index);
            cellStyle12.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle12.setLocked(true); // 显式锁定
            XSSFFont fontBoldItalic12 = wb.createFont();
            fontBoldItalic12.setBold(true);
            fontBoldItalic12.setItalic(true);
            XSSFRichTextString cellValue12 = new XSSFRichTextString();
            cellValue12.append("Name", fontBoldItalic12);
            cell12.setCellValue(cellValue12);
            cell12.setCellStyle(cellStyle12);

            // 第1行其他单元格及数据验证逻辑保留,注意所有单元格样式添加setLocked(true)
            Cell cell13 = row1.createCell(2);
            XSSFDataValidation dv = null;
            XSSFDataValidationConstraint dvc = null;
            XSSFDataValidationHelper dvh = null;
            CellRangeAddressList addList = new CellRangeAddressList(1, 1, 2, 4);
            sheet1.addMergedRegion(new CellRangeAddress(1, 1, 2, 4));
            dvh = new XSSFDataValidationHelper(sheet1);
            dvc =(XSSFDataValidationConstraint) dvh.createFormulaListConstraint("Defination!$A$2:$A$" + 40);
            dv = (XSSFDataValidation) dvh.createValidation(dvc, addList);
            dv.setSuppressDropDownArrow(true);
            sheet1.addValidationData(dv);
            // 给该合并单元格的左上角设置锁定样式
            CellStyle cellStyle13 = wb.createCellStyle();
            cellStyle13.setFillBackgroundColor(IndexedColors.BROWN.index);
            cellStyle13.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle13.setLocked(true);
            cell13.setCellStyle(cellStyle13);

            // 第2行:设置为不可编辑,原有逻辑保留,所有单元格样式添加setLocked(true)
            Row row2 = sheet1.createRow(2);
            CellStyle cellStyle17 = wb.createCellStyle();
            cellStyle17.setFillBackgroundColor(IndexedColors.LIME.index);
            cellStyle17.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle17.setLocked(true);
            XSSFRichTextString cellValue17 = null;
            
            CellStyle cellStyle18 = wb.createCellStyle();
            cellStyle18.setFillBackgroundColor(IndexedColors.CORAL.index);
            cellStyle18.setAlignment(CellStyle.ALIGN_CENTER);
            cellStyle18.setLocked(true);
            XSSFRichTextString cellValue18 = null;
            int k = 1;
            for(int j=0;j<27;j++){
                Cell cell17 = row2.createCell(j);
                if(j < 7){
                    cellValue17 = new XSSFRichTextString();
                    switch(j){
                        case 0: cellValue17.append("Class", fontBoldItalic); break;
                        case 1: cellValue17.append("Student_ID", fontBoldItalic); break;
                        case 2: cellValue17.append("Birth_Date", fontBoldItalic); break;
                        case 3: cellValue17.append("Section", fontBoldItalic); break;
                        case 4: cellValue17.append("Strength", fontBoldItalic); break;
                        case 5: cellValue17.append("Subject", fontBoldItalic); break;
                        case 6: cellValue17.append("Marks", fontBoldItalic); break;
                    }
                    cell17.setCellValue(cellValue17);
                    cell17.setCellStyle(cellStyle17);
                } else {
                    cellValue18 = new XSSFRichTextString();
                    cellValue18.append("Field_"+k, fontBoldItalic);
                    cell17.setCellValue(cellValue18);
                    cell17.setCellStyle(cellStyle18);
                    k++;
                }
            }

            // 创建可编辑行示例:第3行及以后应用解锁样式
            Row editableRow = sheet1.createRow(3);
            for(int j=0;j<27;j++){
                Cell cell = editableRow.createCell(j);
                cell.setCellValue("可编辑内容");
                cell.setCellStyle(editableStyle);
            }

            // 开启工作表保护,密码为"0"
            sheet1.protectSheet("0");

            wb.write(fileOut);
            fileOut.close();

        }  catch (IOException e){
            e.printStackTrace();
        }
    }
}

关键注意点

  • 合并单元格的锁定状态由左上角单元格的样式决定,无需给合并区域所有单元格重复设置
  • 若需批量处理指定行,可遍历这些行的所有单元格,为其样式设置setLocked(true)
  • 必须开启工作表保护,否则所有锁定设置都不会生效

内容的提问来源于stack exchange,提问作者Shashank Rastogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 12:37:09