如何限制生成的excel某列不可编辑?

作者站长头像
站长
· 阅读数 26

背景:

项目技术栈: vue3 + vite;导出数据用到的第三方库:exceljs;

  1. 有一个列表,前端批量导出,生成excel文件,诸如:如何限制生成的excel某列不可编辑?
  2. 但是生成的的excel文件每列都可以修改,和预期不符,预期效果: 序号、班级、姓名都不可以修改,只有得分列可以修改。
回复
1个回答
avatar
test
2024-06-18
 npm install exceljs file-saver
<template>
  <div>
    <button @click="exportToExcel">导出Excel</button>
  </div>
</template>

<script>
import ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';

export default {
  name: 'ExportExcel',
  methods: {
    async exportToExcel() {
      const workbook = new ExcelJS.Workbook();
      const worksheet = workbook.addWorksheet('成绩单');

      // 添加标题行
      worksheet.addRow(['序号', '班级', '姓名', '得分']);

      // 添加数据行
      const data = [
        [1, '六年级三班', 'Buer', 99],
        [2, '六年级一班', 'Jack', 86],
        [3, '六年级三班', 'Mary', 58],
      ];

      data.forEach(row => {
        worksheet.addRow(row);
      });

      // 保护整个工作表
      worksheet.protect('yourpassword', {
        selectLockedCells: true,
        selectUnlockedCells: true,
      });

      // 解锁“得分”列
      worksheet.getColumn(4).eachCell((cell, rowNumber) => {
        if (rowNumber !== 1) { // 跳过标题行
          cell.protection = { locked: false };
        }
      });

      // 将工作簿写入文件
      const buffer = await workbook.xlsx.writeBuffer();
      const blob = new Blob([buffer], { type: 'application/octet-stream' });
      saveAs(blob, '成绩单.xlsx');
    }
  }
};
</script>
  1. 保护整个工作表:通过 worksheet.protect('yourpassword', { ... }) 方法保护整个工作表。
  2. 解锁特定列:通过 worksheet.getColumn(4).eachCell((cell, rowNumber) => { ... }) 方法遍历“得分”列的每个单元格,并将其 protection.locked 属性设置为 false 以解锁该列。answer imageanswer image

要确保只保护某些列,而不是整个工作表,并且允许用户编辑“得分”列,你可以尝试以下方式。这种方式不会保护整个工作表,而是只保护特定的单元格。这可以确保用户在试图编辑受保护单元格时会被提示输入密码,而非直接禁止操作。

<template>
  <div>
    <button @click="exportToExcel">导出Excel</button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';

const exportToExcel = async () => {
  const workbook = new ExcelJS.Workbook();
  const worksheet = workbook.addWorksheet('成绩单');

  // 添加标题行
  const headerRow = worksheet.addRow(['序号', '班级', '姓名', '得分']);

  // 添加数据行
  const data = [
    [1, '六年级三班', 'Buer', 99],
    [2, '六年级一班', 'Jack', 86],
    [3, '六年级三班', 'Mary', 58],
  ];

  data.forEach(row => {
    worksheet.addRow(row);
  });

  // 保护整个工作表并设置密码
  worksheet.protect('yourpassword', {
    selectLockedCells: true,
    selectUnlockedCells: true,
  });

  // 解锁“得分”列
  worksheet.getColumn(4).eachCell((cell, rowNumber) => {
    if (rowNumber !== 1) { // 跳过标题行
      cell.protection = { locked: false };
    }
  });

  // 确保其他列被锁定
  for (let col = 1; col <= 3; col++) {
    worksheet.getColumn(col).eachCell((cell, rowNumber) => {
      if (rowNumber !== 1) { // 跳过标题行
        cell.protection = { locked: true };
      }
    });
  }

  // 将工作簿写入文件
  const buffer = await workbook.xlsx.writeBuffer();
  const blob = new Blob([buffer], { type: 'application/octet-stream' });
  saveAs(blob, '成绩单.xlsx');
};
</script>

解释:1.保护整个工作表:通过 worksheet.protect('yourpassword', { ... }) 方法保护整个工作表。

2.解锁“得分”列:通过 worksheet.getColumn(4).eachCell((cell, rowNumber) => { ... }) 方法遍历“得分”列的每个单元格,并将其 protection.locked 属性设置为 false 以解锁该列。

3.锁定其他列:通过 worksheet.getColumn(col).eachCell((cell, rowNumber) => { ... }) 方法遍历其他列的每个单元格,并将其 protection.locked 属性设置为 true 以锁定这些列。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容