HarmonyOS 鸿蒙Next中使用报错@archermind/exceljs:Cannot read property date1904 of undefined

HarmonyOS 鸿蒙Next中使用报错@archermind/exceljs:Cannot read property date1904 of undefined

import ExcelJS from '[@archermind](/user/archermind)/exceljs';
import { fileIo as fs } from '@kit.CoreFileKit';
import { picker } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';

/**
 * 封装excel工具类
 */

interface ExcelData {
  id: string;
  name: string;
  value: string;
}

// 读取Excel文件并解析数据
async function readExcelWithExcelJS(context: common.UIAbilityContext) {
  try {
    let documentPicker = new picker.DocumentViewPicker(context);
    // 1. 选择本地Excel文件(.xlsx)
    const result = await documentPicker.select({
      maxSelectNumber: 1,
      fileSuffixFilters: ['xlsx', 'xls'],
    });
    if (!result || result.length === 0) {
      console.log('未选择文件');
      return;
    }
    const uri = result[0]; // 获取文件URI

    const file = fs.openSync(uri, fs.OpenMode.READ_ONLY); // 打开文件
    const fileStat = await fs.stat(file.fd); // 获取文件信息
    const buffer = new ArrayBuffer(fileStat.size); // 创建缓冲区
    await fs.read(file.fd, buffer); // 读取文件内容到缓冲区
    fs.closeSync(file.fd); // 关闭文件描述符

    // 3. 使用[@archermind](/user/archermind)/exceljs解析Excel
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.read(buffer);

    // 4. 获取第一个工作表并解析数据
    let worksheet = workbook.getWorksheet(1); // 获取第1个工作表(索引从1开始)
    const excelData: ExcelData[] = [];

    // 遍历行(跳过表头,从第2行开始)
    worksheet?.eachRow({ includeEmpty: false }, (row, rowNumber) => {
      if (rowNumber === 1) {
        return;
      } // 跳过表头行
      let rowData: ExcelData = {
        id: row.getCell(1).value as string, // 第1列
        name: row.getCell(2).value as string, // 第2列
        value: row.getCell(3).value as string, // 第3列
      };
      excelData.push(rowData);
    });
    console.log('解析完成,数据量:', excelData.length);
    return excelData;
  } catch (err) {
    console.error('Excel解析失败:', err);
    return [];
  }
}

export {
  readExcelWithExcelJS
}

更多关于HarmonyOS 鸿蒙Next中使用报错@archermind/exceljs:Cannot read property date1904 of undefined的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

从这个库的github 地址发现,这个貌似是这个库的一个bug

从他们多次的更新日志上看这个问题一直存在

https://github.com/exceljs/exceljs?tab=readme-ov-file

在 V4.1.0 版本中

https://github.com/exceljs/exceljs/pull/1328

中有具体的说明

建议你更新最新的库,或者直接提Issues

更多关于HarmonyOS 鸿蒙Next中使用报错@archermind/exceljs:Cannot read property date1904 of undefined的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


【错误原因】

出现@archermind/exceljs:Cannot read property date1904 of undefined这个错误是由ExcelJS内部错误导致的

【解决方案】

我验证了一下尝试换一种方式还是存在问题:楼主可以看下面的方法对你有没有帮助

async function readExcelWithExcelJS(context: common.UIAbilityContext): Promise<ExcelData[]> {
  try {
    const documentPicker = new picker.DocumentViewPicker(context);
    const result = await documentPicker.select({
      maxSelectNumber: 1,
      fileSuffixFilters: ['xlsx', 'xls'],
    });

    if (!result || result.length === 0) {
      console.log('未选择文件');
      return [];
    }

    const uri = result[0];
    const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
    const fileStat = await fs.stat(file.fd);
    const buffer = new ArrayBuffer(fileStat.size);
    await fs.read(file.fd, buffer);
    fs.closeSync(file.fd);

    // 写入到临时沙箱文件
    const tempPath = `${context.filesDir}/temp.xlsx`;
    const tempFile = fs.openSync(tempPath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY);
    console.log('tempFile object:', tempFile);

    // 自动兼容 fd / fileDescriptor
    const fileDescriptor = tempFile.fd
    if (fileDescriptor === undefined) {
      throw new Error('无法获取文件描述符,请检查 CoreFileKit 版本');
    }

    await fs.write(fileDescriptor, buffer);
    fs.closeSync(fileDescriptor);

    console.log('文件已写入临时路径:', tempPath);

    // 使用 ExcelJS 解析
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.readFile(tempPath);

    const worksheet = workbook.getWorksheet(1);
    if (!worksheet) {
      console.error('无法读取工作表,请检查文件格式');
      return [];
    }

    const excelData: ExcelData[] = [];
    worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
      if (rowNumber === 1) {
        return;
      }
      excelData.push({
        id: String(row.getCell(1).value ?? ''),
        name: String(row.getCell(2).value ?? ''),
        value: String(row.getCell(3).value ?? ''),
      });
    });

    console.log('解析完成,数据量:', excelData.length);
    return excelData;

  } catch (err) {
    console.error('Excel解析失败:', err);
    return [];
  }
}

在HarmonyOS Next中使用@archermind/exceljs报错,原因是该库依赖Node.js环境,而鸿蒙Next不支持Node.js API。错误信息表明无法读取未定义的date1904属性,这通常是因为缺少必要的环境变量或初始化配置。鸿蒙应用应使用官方提供的文件处理API,如@ohos.fileio和@ohos.util,直接操作Excel文件。建议改用鸿蒙原生文件处理方案,避免第三方Node.js库的兼容性问题。

这个错误通常是由于ExcelJS库在解析Excel文件时无法正确读取文件属性导致的。具体来说,date1904是Excel文件中的一个属性,表示是否使用1904日期系统。

在HarmonyOS Next环境中,可能的原因包括:

  1. 文件格式问题:选择的Excel文件可能损坏或不完整
  2. 缓冲区数据问题:从文件读取到ArrayBuffer的数据可能不完整或格式不正确
  3. 库兼容性问题@archermind/exceljs在HarmonyOS Next环境下的特定兼容性问题

建议检查以下几点:

  • 确保选择的Excel文件是有效的.xlsx或.xls文件
  • 验证文件读取过程是否完整,可以在读取后检查buffer的byteLength
  • 尝试使用不同的Excel文件进行测试
  • 检查@archermind/exceljs的版本是否与HarmonyOS Next兼容

可以在读取buffer后添加调试代码:

console.log('Buffer size:', buffer.byteLength);

如果问题持续存在,可能需要考虑使用其他Excel处理库或检查文件选择环节是否存在问题。

回到顶部