Files
junhong_cmp_fiber/docs/excel-import-frontend-guide.md
huang d309951493
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m33s
feat(import): 用 Excel 格式替换 CSV 导入
- 删除 CSV 解析代码,新增 Excel 解析器 (excelize)

- 更新 IoT 卡和设备导入任务处理器

- 更新 API 路由文档和前端接入指南

- 归档变更到 openspec/changes/archive/

- 同步 delta specs 到 main specs
2026-01-31 14:13:02 +08:00

5.5 KiB

Excel导入功能 - 前端接入指南

变更说明

导入功能已从CSV格式升级为Excel格式(.xlsx),解决长数字(如20位ICCID)被Excel自动转为科学记数法导致数据损坏的问题。

关键变更

1. 文件格式

项目 旧版本(CSV) 新版本(Excel)
文件扩展名 .csv .xlsx
MIME类型 text/csv application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
文件选择器accept *.csv .xlsx

2. 上传示例代码

ICCID导入:

// 1. 获取预签名URL
const response = await api.post('/api/admin/storage/upload-url', {
  file_name: 'cards.xlsx',  // 修改扩展名
  content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',  // 修改MIME类型
  purpose: 'iot_import'
});

const { upload_url, file_key } = response.data;

// 2. 上传Excel文件到对象存储
await fetch(upload_url, {
  method: 'PUT',
  headers: { 
    'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'  // 修改MIME类型
  },
  body: file  // File对象来自<input type="file" accept=".xlsx">
});

// 3. 提交导入任务
await api.post('/api/admin/iot-cards/import', {
  carrier_id: 1,
  batch_no: 'BATCH-2025-01',
  file_key: file_key
});

设备导入: 流程相同,只需调用 /api/admin/devices/import 接口。

3. 文件选择器组件

修改前:

<input type="file" accept="*" />
<!-- 或 -->
<input type="file" accept=".csv" />

修改后:

<input type="file" accept=".xlsx" />

4. 文件验证

function validateFile(file) {
  // 检查扩展名
  if (!file.name.toLowerCase().endsWith('.xlsx')) {
    throw new Error('仅支持上传Excel文件(.xlsx格式)');
  }
  
  // 检查MIME类型(可选,部分浏览器可能不准确)
  const validTypes = [
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/octet-stream'  // 部分浏览器可能返回此类型
  ];
  
  if (!validTypes.includes(file.type)) {
    console.warn('文件MIME类型不匹配,但根据扩展名判断为有效文件');
  }
  
  return true;
}

Excel模板文件

ICCID导入模板

文件名: iccid_import_template.xlsx

格式:

ICCID MSISDN
89860012345678901234 13800000001
89860012345678901235 13800000002

要点:

  • 必须包含表头行(ICCID, MSISDN)
  • ICCID和MSISDN列必须设置为文本格式(重要!)
  • Excel中设置文本格式: 选中列 → 右键 → 设置单元格格式 → 文本

设备导入模板

文件名: device_import_template.xlsx

格式:

device_no device_name device_model device_type max_sim_slots manufacturer iccid_1 iccid_2 iccid_3 iccid_4
DEV-001 GPS追踪器A GT06N GPS Tracker 4 Concox 89860012345678901234 89860012345678901235
DEV-002 GPS追踪器B GT06N GPS Tracker 4 Concox 89860012345678901236

要点:

  • 所有列都必须设置为文本格式
  • device_no为必填项
  • iccid_1 ~ iccid_4为可选项,填写时对应的ICCID必须已存在于系统中

模板下载功能实现

// 方案1: 后端提供静态文件下载
<a href="/api/admin/storage/templates/iccid_import_template.xlsx" download>
  下载ICCID导入模板
</a>

// 方案2: 前端本地存放模板文件
<a href="/assets/templates/iccid_import_template.xlsx" download>
  下载ICCID导入模板
</a>

建议使用方案2(前端本地存放),减轻后端负担。

错误处理

服务端错误示例

{
  "code": 1,
  "msg": "不支持的文件格式 .csv,请上传Excel文件(.xlsx)",
  "timestamp": "2025-01-31T13:00:00Z"
}

前端错误提示

try {
  await uploadAndImport(file);
} catch (error) {
  if (error.response?.data?.msg) {
    // 显示服务端返回的错误消息
    showError(error.response.data.msg);
  } else {
    showError('上传失败,请重试');
  }
}

迁移检查清单

  • 修改文件选择器accept属性为 .xlsx
  • 更新上传时的MIME类型为Excel格式
  • 添加前端文件格式验证(扩展名检查)
  • 准备Excel模板文件并放置到前端资源目录
  • 添加"下载模板"按钮/链接
  • 更新相关提示文案(CSV → Excel)
  • 测试完整的上传流程
  • 验证错误场景(上传CSV文件时的提示)

注意事项

  1. 向后兼容: 本次变更不向后兼容,旧的CSV文件无法使用,前端需同步更新
  2. 用户通知: 建议在界面上添加醒目提示,告知用户格式变更
  3. 模板文件: 模板文件中的ICCID列必须设置为文本格式,否则长数字会被Excel自动转为科学记数法
  4. 文件大小: Excel文件比CSV大3-5倍,但对1万行数据影响不大(约3-5MB)

常见问题

Q: 为什么要从CSV改为Excel?
A: Excel编辑CSV时会将超过15位的长数字(如20位ICCID)自动转为科学记数法,导致数据损坏。使用Excel格式并设置为文本格式可彻底解决此问题。

Q: 用户已经准备好的CSV文件怎么办?
A: 用户可以在Excel中打开CSV,将ICCID/MSISDN列设置为文本格式,然后另存为.xlsx格式即可。

Q: 是否支持.xls(旧版Excel)?
A: 不支持。仅支持.xlsx (Excel 2007+),建议在文档中明确说明。

联系方式

如有问题,请联系后端开发团队。