1.0.13 • Published 2 months ago

@sparta-utils/excel-validate-helper v1.0.13

Weekly downloads
-
License
MIT
Repository
-
Last release
2 months ago

@sparta-utils/excel-validate-helper

Excel 读取、校验、错误标注和导出工具库,基于 exceljs

目录


安装

你可以通过 npm 或 yarn 直接安装本库:

npm install @sparta-utils/excel-validate-helper
# 或
yarn add @sparta-utils/excel-validate-helper

使用示例

import {
  ExcelReader,
  ExcelValidator,
  ExcelMarker,
  ExcelExporter
} from '@sparta-utils/excel-validate-helper';

async function processExcel(file: File) {
  // 1. 读取文件
  const  = await ExcelReader.read(file, 4);
  const { headers, data } = await ExcelReader.read(file, {
    dataStartRow: 4,
    sheetIndex: 0,
    onProgress: (progress) => {
      console.log(`读取进度:${progress}%`)
    },
    mapHeaders: (header) => header.trim(),
    filterEmptyRows: true, // 过滤空行
    progressStep: 5, // 进度5%通知一次
  })
  console.log('表头:', headers);
  console.log('数据:', data);

  // 2. 校验数据
  const result = ExcelValidator.validate(data, {
    colHeaders: ['姓名', '身份证', '手机号', '年龄', '邮箱'],
    fieldNames: ['name', 'idCard', 'phone', 'age', 'email'],
    rules: {
      0: { required: true },
      1: { required: true, pattern: ExcelValidator.getPredefinedPattern('idCard') },
      2: { pattern: ExcelValidator.getPredefinedPattern('phone') },
      3: { type: 'number', min: 18, max: 65 },
      4: { pattern: ExcelValidator.getPredefinedPattern('email') }
    },
    uniqueGroupCols: [1, 2], // 身份证 + 手机号联合唯一
    onProgress: (current, total) => {
      console.log(`校验进度: ${current}/${total}`)
    }
  })


  if (result.err.length) {
    console.warn('校验失败:', result.err);

    // 3. 标注错误

    // const errors: CellError[] = [
    //   { row: 2, col: 3, reason: '缺失必填项', level: 'error' },
    //   { row: 3, col: 2, reason: '数值超限', level: 'warning' },
    //   { row: 4, col: 5, reason: '格式建议', level: 'info' },
    //   { row: 6, col: 1, reason: '跨 Sheet 错误', sheetName: 'Sheet2' }
    // ]
    const errors: CellError[] = result.err

    const options = {
      outputType: 'both', //错误输出方式(默认 note)
      allowMultiSheet: true, // 是否支持多sheet标记
      errorColumnTitle: '数据校验信息', // 错误信息列标题
      errorColumnIndex: 10 // 错误信息输入的列,不传则默认最后一列
    }
    const markedBlob = await ExcelMarker.markErrors(file, errors, options)

    // 4. 导出带标注的Excel
    ExcelExporter.export(markedBlob, {
      fileName: '错误标注.xlsx',
      format: 'xlsx',
      onSuccess: () => {
        console.log('✅ 文件导出成功')
      },
      onError: (err) => {
        console.error('❌ 导出失败', err)
      },
      onProgress: (progress) => {
        console.log(`进度:${progress}%`)
      }
    })
  } else {
    console.log('校验通过,数据:', result.succ);
    // 继续业务逻辑处理 result.succ
  }
}

包中方法介绍

  • 本包导出了四个核心类:

1. ExcelReader


ExcelReader 是一个基于 ExcelJS 的前端 Excel 读取工具类,支持读取 .xlsx 文件,灵活配置数据起始行、工作表索引、进度回调、数据映射与空行过滤,方便你快速将 Excel 文件转换为结构化数据,适合用于表格导入、数据展示等场景。

  • 快速使用示例
import { ExcelReader } from './ExcelReader'

const fileInput = document.getElementById('fileInput') as HTMLInputElement

fileInput.addEventListener('change', async () => {
  const file = fileInput.files?.[0]
  if (!file) return

  try {
    const result = await ExcelReader.read(file, {
      dataStartRow: 4,
      sheetIndex: 0,
      onProgress: (progress) => {
        console.log(`读取进度:${progress}%`)
      },
      mapHeaders: (header) => header.trim(),
      mapRow: (row) => row.map(cell => (typeof cell === 'string' ? cell.trim() : cell)),
      filterEmptyRows: true,
      progressStep: 5,
    })

    console.log('读取完成:', result)
  } catch (error) {
    console.error('读取出错:', error)
  }
})

参数说明

参数名类型说明默认值
dataStartRownumber数据开始行,Excel 中第几行开始读取数据,前一行为表头。例如4表示第4行开始读取数据(第3行为表头)4
sheetIndexnumber读取第几个工作表,索引从0开始0
onProgress(progress: number) => void读取进度回调,参数为百分比,例如50表示完成一半
mapHeaders(header: string) => string表头映射函数,用于对表头字符串进行自定义处理,如去除空格、大小写转换
mapRow(row: any[]) => any[]行数据映射函数,用于对每行数据做转换处理,如去除单元格空格、类型转换等
filterEmptyRowsboolean是否过滤全为空的行,避免读取无效数据行true
progressStepnumber进度回调的最小步长,避免频繁触发回调5
  • 返回结果 函数返回一个 Promise,resolve 一个对象,结构如下:
interface ExcelReadResult {
  headers: string[]        // 读取的表头字段数组,顺序对应数据列
  data: any[][]           // 读取的数据二维数组,每一行为一条数据,首列是 Excel 行号
  totalRows: number        // 当前工作表总行数
  sheetName: string        // 当前读取的工作表名称
  fileName: string         // 上传的 Excel 文件名
}
  • mapHeaders 使用示例及功能

mapHeaders 是一个函数,用于对 Excel 表头字符串进行处理。它接受一个字符串参数(当前表头文本),返回一个字符串(处理后的表头)。 常见用法包括: 去除表头两端空白字符 替换或重命名表头字段 转换为驼峰命名或小写 示例:

const mapHeaders = (header: string): string => {
  // 去空格并转为小写驼峰
  return header.trim().replace(/\s+(\w)/g, (_, c) => c.toUpperCase())
}
示例应用:
const result = await ExcelReader.read(file, {
  mapHeaders,
})
console.log(result.headers)
  • mapRow 使用示例及功能 mapRow 是一个函数,用于对读取的每行数据进行自定义处理。它接受一个数组参数(该行所有单元格数据,不含行号),返回一个处理后的数组。 常见用法包括: 去除每个单元格字符串的空白字符 类型转换,比如将数字字符串转换为数字 日期格式化 数据校验和修正 示例:
const mapRow = (row: any[]): any[] => {
  return row.map(cell => {
    if (typeof cell === 'string') {
      return cell.trim()
    }
    if (typeof cell === 'number') {
      return cell
    }
    // 你也可以增加对日期、布尔值等特殊处理
    return cell
  })
}
示例应用:
const result = await ExcelReader.read(file, {
  mapRow,
})
console.log(result.data)

2. ExcelValidator


一个功能强大且灵活的 Excel 数据校验工具,支持常用验证规则、列唯一、组合列唯一、自定义规则等。易用且向下兼容,适合日常 Excel 数据导入校验场景。

功能特点:

  • 支持必填项、数字范围、邮箱、手机号、身份证等常用规则校验
  • 支持单列唯一校验
  • 支持组合列唯一校验(多列拼接判断唯一)
  • 支持自定义正则表达式规则
  • 支持自定义函数校验
  • 数字类型自动 trim + 转换成数字
  • 验证错误定位准确,支持 Excel 行号(从1开始)、列号(从0开始)
  • 进度回调支持大数据场景

API 参数说明

参数名类型说明
colHeadersstring[]Excel 列标题,用于错误提示
fieldNamesstring[]字段映射,用于生成结果对象
rulesRecord<number, ColumnRule>校验规则集合,key 是列索引
uniqueGroupColsnumber[]组合唯一校验列索引数组,列值拼接做唯一性检查
startRowIndexnumber起始行号(默认2),对应 Excel 实际行号
onProgress(curr: number, total: number) => void校验进度回调
  • 校验规则 ColumnRule 说明 | 属性 | 类型 | 说明 | | ---------- | ----------------------------------------------------------------- | ---------------------------------------- | | required | boolean | 是否必填 | | type | 'string' \| 'number' \| 'boolean' \| 'date' | 数据类型,number 会自动 trim 和转数字 | | pattern | RegExp | 自定义正则表达式校验 | | min | number | 数字类型最小值 | | max | number | 数字类型最大值 | | unique | boolean | 该列是否要求唯一(全表) | | custom | (val: any, row: any[], rowIndex: number) => string \| undefined | 自定义校验函数,返回错误信息表示校验失败,返回 undefined 表示通过 |
  • 内置常用正则模板 可以通过 ExcelValidator.getPredefinedPattern(name) 获取,支持: | 名称 | 说明 | | -------- | ----- | | idCard | 身份证号码 | | phone | 手机号码 | | tel | 固话号码 | | email | 邮箱地址 |
  • 使用示例
const result = ExcelValidator.validate(data, {
  colHeaders: ['姓名', '身份证', '手机号', '年龄', '邮箱'],
  fieldNames: ['name', 'idCard', 'phone', 'age', 'email'],
  rules: {
    0: { required: true },
    1: { required: true, pattern: ExcelValidator.getPredefinedPattern('idCard') },
    2: { pattern: ExcelValidator.getPredefinedPattern('phone') },
    3: { type: 'number', min: 18, max: 65 },
    4: { pattern: ExcelValidator.getPredefinedPattern('email') }
  },
  uniqueGroupCols: [1, 2], // 身份证 + 手机号联合唯一
  onProgress: (current, total) => {
    console.log(`校验进度: ${current}/${total}`)
  }
})

1. 基础规则配置示例

const rules = {
  0: { required: true },                            // 姓名必填
  1: { required: true, pattern: ExcelValidator.getPredefinedPattern('idCard') }, // 身份证必填且格式正确
  2: { pattern: ExcelValidator.getPredefinedPattern('phone') },  // 手机号格式校验
  3: { type: 'number', min: 18, max: 60 },          // 年龄数字范围校验
  4: { pattern: ExcelValidator.getPredefinedPattern('email') }   // 邮箱格式校验
}

2. 单列唯一校验
const rules = {
  1: { unique: true }  // 身份证号列唯一
}

3. 组合列唯一校验
const uniqueGroupCols = [1, 2]  // 身份证 + 手机号 联合唯一

4. 自定义正则表达式
const rules = {
  5: { pattern: /^[A-Z]{3}\d{4}$/ } // 第6列必须是3个大写字母+4个数字
}

5. 自定义函数校验
const rules = {
  3: {
    custom: (val, row, rowIndex) => {
      if (val < 0 || val > 100) return '数值必须在0到100之间'
      if (row[0] === '特殊标记' && val < 50) return '特殊标记项最小值为50'
      return undefined
    }
  }
}

返回结果结构
{
  err: CellError[], // 错误列表,每条包括 Excel 行号、列号及错误原因
  succ: any[]       // 解析成功后的对象数组,字段名对应 fieldNames 配置
}

3. ExcelMarker


ExcelMarker 是一个基于 ExcelJS 的轻量级工具类,用于在 Excel 文件中标注错误单元格、批注或添加错误列信息,支持错误等级样式、跨 Sheet 标注、灵活输出方式等。

  • ✨ 功能特性

  • ✅ 支持单元格错误标注:添加批注、修改样式

  • ✅ 支持错误等级样式(error/warning/info)
  • ✅ 支持在额外列中记录每行错误信息
  • ✅ 支持不同 Sheet 多处错误标注
  • ✅ 支持自定义“错误列”插入位置
  • ✅ 支持批注(note)、错误列(column)、或二者同时输出(both)

  • 📚 API 使用说明 ExcelMarker.markErrors(file, errors, options?)

参数说明 | 参数 | 类型 | 必填 | 说明 | | --------- | --------------- | -- | ------------------------ | | file | File | ✅ | 待处理的 Excel 文件对象(.xlsx) | | errors | CellError[] | ✅ | 错误信息数组,包含具体行列、等级、原因等 | | options | MarkerOptions | ❌ | 标注配置项,详见下方 |

CellError 类型定义

interface CellError {
  row: number              // 行号(从 1 开始)
  col: number              // 列号(从 1 开始)
  reason?: string          // 错误原因(默认显示 defaultNote)
  level?: 'error' | 'warning' | 'info'   // 错误等级(默认 error)
  sheetName?: string       // 错误所在 sheet 名(需开启 allowMultiSheet)
}

MarkerOptions 类型定义

interface MarkerOptions {
  style?: CellStyle               // 自定义样式覆盖默认错误样式
  defaultNote?: string           // 当错误无 reason 时的默认批注内容
  outputType?: 'note' | 'column' | 'both'  // 错误输出方式(默认 note)
  sheetName?: string             // 默认工作表名称(若未指定 error.sheetName)
  errorColumnTitle?: string      // 错误列标题(默认 "错误信息")
  allowMultiSheet?: boolean      // 是否允许跨 Sheet 标注(默认 false)
  errorColumnIndex?: number      // 错误列插入位置(默认追加在最后)
}

CellStyle(可选样式覆盖)

interface CellStyle {
  font?: Partial<ExcelJS.Font>
  alignment?: Partial<ExcelJS.Alignment>
  fill?: Partial<ExcelJS.Fill>
  border?: Partial<ExcelJS.Borders>
}
  • 🧪 示例代码
import { ExcelMarker, CellError } from './ExcelMarker'

const file = fileInput.files[0]  // 来自 <input type="file" />

const errors: CellError[] = [
  { row: 2, col: 3, reason: '缺失必填项', level: 'error' },
  { row: 3, col: 2, reason: '数值超限', level: 'warning' },
  { row: 4, col: 5, reason: '格式建议', level: 'info' },
  { row: 6, col: 1, reason: '跨 Sheet 错误', sheetName: 'Sheet2' }
]

const options = {
  outputType: 'both',
  allowMultiSheet: true,
  errorColumnTitle: '数据校验信息',
  errorColumnIndex: 10
}

ExcelMarker.markErrors(file, errors, options).then(blob => {
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = '标注后的数据.xlsx'
  link.click()
  URL.revokeObjectURL(url)
})
  • 🎨 错误等级样式说明 | Level | 背景色 | 字体颜色 | 描述 | | --------- | ------------- | --------- | ---- | | error | #FFC7CE(红) | #FF0000 | 严重错误 | | warning | #FFEB9C(黄) | #996600 | 警告提示 | | info | #C6EFCE(蓝绿) | #0000FF | 信息提示 |

你可以通过 style 参数进一步自定义颜色、边框、对齐方式等样式细节。

  • 🛠 依赖 ExcelJS

4. ExcelExporter


一个功能强大且灵活的 Excel 数据校验工具,支持常用验证规则、列唯一、组合列唯一、自定义规则等。易用且向下兼容,适合日常 Excel 数据导入校验场景。

  • 功能特点

  • 支持必填项、数字范围、邮箱、手机号、身份证等常用规则校验

  • 支持单列唯一校验
  • 支持组合列唯一校验(多列拼接判断唯一)
  • 支持自定义正则表达式规则
  • 支持自定义函数校验
  • 数字类型自动 trim + 转换成数字
  • 验证错误定位准确,支持 Excel 行号(从1开始)、列号(从0开始)
  • 进度回调支持大数据场景

  • API 参数说明 | 参数名 | 类型 | 说明 | | ----------------- | --------------------------------------- | ----------------------- | | colHeaders | string[] | Excel 列标题,用于错误提示 | | fieldNames | string[] | 字段映射,用于生成结果对象 | | rules | Record<number, ColumnRule> | 校验规则集合,key 是列索引 | | uniqueGroupCols | number[] | 组合唯一校验列索引数组,列值拼接做唯一性检查 | | startRowIndex | number | 起始行号(默认2),对应 Excel 实际行号 | | onProgress | (curr: number, total: number) => void | 校验进度回调 |

  • 校验规则 ColumnRule 说明 | 属性 | 类型 | 说明 | | ---------- | ----------------------------------------------------------------- | ---------------------------------------- | | required | boolean | 是否必填 | | type | 'string' \| 'number' \| 'boolean' \| 'date' | 数据类型,number 会自动 trim 和转数字 | | pattern | RegExp | 自定义正则表达式校验 | | min | number | 数字类型最小值 | | max | number | 数字类型最大值 | | unique | boolean | 该列是否要求唯一(全表) | | custom | (val: any, row: any[], rowIndex: number) => string \| undefined | 自定义校验函数,返回错误信息表示校验失败,返回 undefined 表示通过 |

  • 内置常用正则模板 可以通过 ExcelValidator.getPredefinedPattern(name) 获取,支持: | 名称 | 说明 | | -------- | ----- | | idCard | 身份证号码 | | phone | 手机号码 | | tel | 固话号码 | | email | 邮箱地址 |
  • 使用示例
const result = ExcelValidator.validate(data, {
  colHeaders: ['姓名', '身份证', '手机号', '年龄', '邮箱'],
  fieldNames: ['name', 'idCard', 'phone', 'age', 'email'],
  rules: {
    0: { required: true },
    1: { required: true, pattern: ExcelValidator.getPredefinedPattern('idCard') },
    2: { pattern: ExcelValidator.getPredefinedPattern('phone') },
    3: { type: 'number', min: 18, max: 65 },
    4: { pattern: ExcelValidator.getPredefinedPattern('email') }
  },
  uniqueGroupCols: [1, 2], // 身份证 + 手机号联合唯一
  onProgress: (current, total) => {
    console.log(`校验进度: ${current}/${total}`)
  }
})


1. 基础规则配置示例

const rules = {
  0: { required: true },                            // 姓名必填
  1: { required: true, pattern: ExcelValidator.getPredefinedPattern('idCard') }, // 身份证必填且格式正确
  2: { pattern: ExcelValidator.getPredefinedPattern('phone') },  // 手机号格式校验
  3: { type: 'number', min: 18, max: 60 },          // 年龄数字范围校验
  4: { pattern: ExcelValidator.getPredefinedPattern('email') }   // 邮箱格式校验
}

2. 单列唯一校验
const rules = {
  1: { unique: true }  // 身份证号列唯一
}

3. 组合列唯一校验
const uniqueGroupCols = [1, 2]  // 身份证 + 手机号 联合唯一

4. 自定义正则表达式
const rules = {
  5: { pattern: /^[A-Z]{3}\d{4}$/ } // 第6列必须是3个大写字母+4个数字
}

5. 自定义函数校验
const rules = {
  3: {
    custom: (val, row, rowIndex) => {
      if (val < 0 || val > 100) return '数值必须在0到100之间'
      if (row[0] === '特殊标记' && val < 50) return '特殊标记项最小值为50'
      return undefined
    }
  }
}

返回结果结构
{
  err: CellError[], // 错误列表,每条包括 Excel 行号、列号及错误原因
  succ: any[]       // 解析成功后的对象数组,字段名对应 fieldNames 配置
}

1.0.13

2 months ago

1.0.12

2 months ago

1.0.11

2 months ago

1.0.10

2 months ago

1.0.9

2 months ago

1.0.8

2 months ago

1.0.7

2 months ago

1.0.6

2 months ago

1.0.5

2 months ago

1.0.4

2 months ago

1.0.3

2 months ago

1.0.2

2 months ago

1.0.1

2 months ago

1.0.0

2 months ago