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

咨询:用JavaScript获取近3个月并验证Fastify服务器上传的Excel年月

解决方案:获取近3个月日期范围 + Fastify Excel年月验证

我来帮你搞定这两个问题——先修复你获取近3个月的代码,再给你梳理Fastify服务器上验证Excel的完整流程。

一、修复「获取过去3个月」的函数

你原来的代码有两个核心问题:

  1. 当当前月份是年初(1月、2月、3月)时,now.getMonth() - i会出现负数,导致取months数组元素时返回undefined
  2. 只返回了月份名称,但验证需要年份+月份的组合(比如跨年度的情况:2018年1月对应的允许月份是2017年10月、11月、12月)

这里给你两种可选的实现,对应你示例里的两种场景:

场景1:允许当前月+往前推2个月(共3个月,匹配2019年10月允许8月的示例)

// 返回允许的年月集合,格式为 Set<`${number}-${string}`>(如'2019-10'),方便快速验证
const getAllowedYearMonths = () => {
  const now = new Date();
  const allowed = new Set();
  
  for (let i = 0; i < 3; i++) {
    const targetDate = new Date(now.getFullYear(), now.getMonth() - i, 1);
    const year = targetDate.getFullYear();
    // 月份补零为两位数字,统一格式避免匹配错误
    const month = String(targetDate.getMonth() + 1).padStart(2, '0');
    allowed.add(`${year}-${month}`);
  }
  
  return allowed;
};

// 示例:当前为2019年10月时,集合包含'2019-10'、'2019-09'、'2019-08'

场景2:允许往前推1-3个月(不包含当前月,匹配2018年1月允许10月的示例)

如果你的需求是完全排除当前月,只允许过去的3个完整月份,只需调整循环起始值:

const getAllowedYearMonths = () => {
  const now = new Date();
  const allowed = new Set();
  
  // 从i=1开始,取往前推1-3个月的日期
  for (let i = 1; i <= 3; i++) {
    const targetDate = new Date(now.getFullYear(), now.getMonth() - i, 1);
    const year = targetDate.getFullYear();
    const month = String(targetDate.getMonth() + 1).padStart(2, '0');
    allowed.add(`${year}-${month}`);
  }
  
  return allowed;
};

// 示例:当前为2018年1月时,集合包含'2017-12'、'2017-11'、'2017-10'

二、Fastify服务器上的Excel验证流程

接下来是在Fastify中处理上传的Excel并验证年月的完整步骤:

1. 安装依赖

先安装处理文件上传和解析Excel的必备库:

npm install @fastify/multipart xlsx

2. Fastify代码实现

const fastify = require('fastify')({ logger: true });
const xlsx = require('xlsx');
const { getAllowedYearMonths } = require('./your-utils-file'); // 导入上面的函数

// 注册文件上传插件
fastify.register(require('@fastify/multipart'));

// 处理Excel上传的路由
fastify.post('/upload-excel', async (request, reply) => {
  try {
    // 获取上传的文件对象
    const file = await request.file();
    if (!file) {
      return reply.status(400).send({ error: '请上传有效的Excel文件' });
    }

    // 读取文件内容为Buffer
    const buffer = await file.toBuffer();
    // 解析Excel工作簿
    const workbook = xlsx.read(buffer, { type: 'buffer' });
    // 取第一个工作表(假设数据在第一个Sheet中)
    const worksheet = workbook.Sheets[workbook.SheetNames[0]];
    // 转换为JSON格式(假设Excel表头为「年份」「月份」)
    const excelData = xlsx.utils.sheet_to_json(worksheet, { header: ['年份', '月份'] });

    // 获取允许的年月集合
    const allowedYearMonths = getAllowedYearMonths();
    // 存储验证失败的行信息
    const invalidRows = [];

    // 遍历数据行(跳过第1行表头)
    for (let i = 1; i < excelData.length; i++) {
      const row = excelData[i];
      const year = row['年份'];
      const month = row['月份'];

      // 基础校验:年份和月份必须是数字
      if (typeof year !== 'number' || typeof month !== 'number') {
        invalidRows.push({
          row: i + 1, // 对应Excel的实际行号(从1开始)
          reason: '年份或月份必须为数字格式'
        });
        continue;
      }

      // 格式化为统一的'YYYY-MM'字符串
      const formattedMonth = String(month).padStart(2, '0');
      const yearMonth = `${year}-${formattedMonth}`;

      // 验证是否在允许范围内
      if (!allowedYearMonths.has(yearMonth)) {
        invalidRows.push({
          row: i + 1,
          reason: `年月${yearMonth}不在允许的近3个月范围内`
        });
      }
    }

    // 返回验证结果
    if (invalidRows.length > 0) {
      return reply.status(400).send({
        error: '存在不合规的年月数据',
        invalidRows
      });
    }

    return reply.send({ message: 'Excel数据验证通过' });
  } catch (err) {
    fastify.log.error('处理Excel上传失败:', err);
    return reply.status(500).send({ error: '服务器内部处理失败' });
  }
});

// 启动服务器
const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
    fastify.log.info(`服务器运行在 http://localhost:${fastify.server.address().port}`);
  } catch (err) {
    fastify.log.error('启动服务器失败:', err);
    process.exit(1);
  }
};

start();

3. 关键细节说明

  • 表头适配:如果你的Excel表头不是「年份」「月份」,需要修改sheet_to_json的header参数,以及后续读取row的字段名。
  • 格式统一:把月份转换为两位数字(如5→'05'),避免出现2024-5和2024-05格式不匹配的问题。
  • 错误反馈:返回具体的错误行号和原因,方便用户快速定位并修改Excel内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:24:00