Возникает ошибка при выполнении скрипта:
В исходном файле Разрешённые для индексации, но нет в sitemap.xml.xlsx не найден лист с индексом 1.

Необходимо исправить и обрабатывать лист, возможно это случилось, из-за того что в этом документе был удален лист ранее вручную. Вот код:
import ExcelJS from 'exceljs';
import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import config from "./config.js"; 

const directoryPath = config.directoryPath;

// Конфигурация пар файлов и соответствующих столбцов
const filePairs = [
  {
    sourceFileName: 'Смешанный контент.xlsx', // Из какого документа
    targetFileName: 'Безопасность. Смешанный контент.xlsx', // В какой документ
    sourceColumns: ['Где найдено', 'Содержимое, загружаемое через HTTP'], // Из каких столбцов перенести данные
    targetColumns: ['Источник', 'Назначение'], // В какие столбцы перенести данные
    keyColumns: ['Источник', 'Назначение'], // Столбцы для проверки дубликатов
  },
  {
    sourceFileName: 'Страницы содержащие битые ссылки.xlsx',
    targetFileName: 'Коды ответа. Ошибка (4xx).xlsx',
    sourceColumns: ['Страница с битой ссылкой', 'Битая ссылка','Код ответа'],
    targetColumns: ['Источник', 'Назначение','Код ответа'],
    keyColumns: ['Источник', 'Назначение', 'Код ответа'], 
  },
  {
    sourceFileName: 'Закрытые от индексации, но есть в sitemap.xml.xlsx',
    targetFileName: 'Sitemap. Неиндексируемые URL в Sitemap.xlsx',
    sourceColumns: ['Страница с битой ссылкой', 'Битая ссылка','Код ответа'],
    targetColumns: ['Источник', 'Назначение','Код ответа'],
    keyColumns: ['Источник', 'Назначение', 'Код ответа'], 
  },
  {
    sourceFileName: 'Разрешённые для индексации, но нет в sitemap.xml.xlsx',
    targetFileName: 'Sitemap. URL не в Sitemap.xlsx',
    sourceColumns: ['Нет в sitemap, но разрешены для индексации', 'HTTP Code'],
    targetColumns: ['Адрес', 'Код ответа'],
    keyColumns: ['Адрес', 'Код ответа'], 
  },
  {
    sourceFileName: 'Изображения с пустым Alt.xlsx',
    targetFileName: 'Изображения. Отсутствует Alt.xlsx',
    sourceColumns: ['SRC изображения', 'Страница, где находится'],
    targetColumns: ['Назначение', 'Источник'],
    keyColumns: ['Назначение', 'Источник'], 
  },
  {
    sourceFileName: 'Ссылки. Страницы без внутренних исходящих ссылок.xlsx',
    targetFileName: 'Нет исходящих.xlsx',
    sourceColumns: ['Адрес', 'Кол-во входящих ссылок'],
    targetColumns: ['Страница', 'Внутренние ссылки'],
    keyColumns: ['Страница', 'Внутренние ссылки'], 
  },
  {
    sourceFileName: 'Страницы с тегом noindex.xlsx',
    targetFileName: 'Директивы. Noindex.xlsx',
    sourceColumns: ['URL'],
    targetColumns: ['Источник'],
    keyColumns: ['Источник'], 
  },
  {
    sourceFileName: 'Тощие страницы.xlsx',
    targetFileName: 'Контент. Страницы где мало контента.xlsx',
    sourceColumns: ['Страница', 'Кол-во слов'],
    targetColumns: ['Адрес', 'Количество слов'],
    keyColumns: ['Адрес', 'Количество слов'], 
  },
  {
    sourceFileName: 'Страницы с одинаковым Title.xlsx',
    targetFileName: 'Title. Дубликаты.xlsx',
    sourceColumns: ['Действие', 'Title'],
    targetColumns: ['Адрес', 'Title 1'],
    keyColumns: ['Адрес', 'Title 1'], 
  },
  {
    sourceFileName: 'Страницы с одинаковым Description.xlsx',
    targetFileName: 'Description. Дубликаты.xlsx',
    sourceColumns: ['Действие', 'Description'],
    targetColumns: ['Адрес', 'Description 1'],
    keyColumns: ['Адрес', 'Description 1'], 
  },
  {
    sourceFileName: 'Страницы c Title = H1.xlsx',
    targetFileName: 'Title. Такой же как и H1.xlsx',
    sourceColumns: ['Страница', 'TITLE'],
    targetColumns: ['Адрес', 'Title 1'],
    keyColumns:  ['Адрес', 'Title 1'], 
  },
  {
    sourceFileName: 'Страницы без Title.xlsx',
    targetFileName: 'Title. Отсутствует.xlsx',
    sourceColumns: ['Страница'],
    targetColumns: ['Адрес'],
    keyColumns:  ['Адрес'], 
  },
  {
    sourceFileName: 'Страницы без H1.xlsx',
    targetFileName: 'H1. Пропущенные.xlsx',
    sourceColumns: ['Страница'],
    targetColumns: ['Адрес'],
    keyColumns: ['Адрес'], 
  },
  {
    sourceFileName: 'Страницы без Description.xlsx',
    targetFileName: 'Description. Отсутствуют.xlsx',
    sourceColumns: ['Страница'],
    targetColumns: ['Адрес'],
    keyColumns: ['Адрес'], 
  },
];

// Функция для получения индексов столбцов
function getColumnIndices(headerRow, columns) {
  const columnIndices = {};
  headerRow.eachCell((cell, colNumber) => {
    const header = cell.value;
    if (columns.includes(header)) {
      columnIndices[header] = colNumber;
    }
  });
  // Добавляем недостающие столбцы
  columns.forEach((column) => {
    if (!columnIndices[column]) {
      const newColNumber = headerRow.cellCount + 1;
      headerRow.getCell(newColNumber).value = column;
      columnIndices[column] = newColNumber;
    }
  });
  return columnIndices;
}

// Функция для удаления дубликатов в одном файле
async function removeDuplicatesInFile(filePath) {
  console.log(chalk.blue(`Обрабатывается файл: ${path.basename(filePath)}`)); // Лог текущего файла

  const workbook = new ExcelJS.Workbook();
  try {
    await workbook.xlsx.readFile(filePath);
  } catch (readError) {
    console.error(chalk.red(`Не удалось прочитать файл ${path.basename(filePath)}: ${readError.message}`));
    return;
  }

  const worksheet = workbook.getWorksheet(1);

  if (!worksheet) {
    console.error(chalk.red(`В файле ${path.basename(filePath)} не найден лист с индексом 1.`));
    return;
  }

  try {
    const rowValuesSet = new Set();
    const rowsToRemove = [];

    worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
      if (rowNumber === 1) return; // Пропустить заголовок
      const rowValues = row.values.slice(1).join('||'); // Объединяем значения ячеек
      if (rowValuesSet.has(rowValues)) {
        rowsToRemove.push(rowNumber);
      } else {
        rowValuesSet.add(rowValues);
      }
    });

    // Удаляем дубликаты, начиная с конца, чтобы не сместить индексы
    rowsToRemove.reverse().forEach((rowNumber) => {
      worksheet.spliceRows(rowNumber, 1);
    });

    if (rowsToRemove.length > 0) {
      await workbook.xlsx.writeFile(filePath);
      console.log(chalk.green(
        `Удалено ${rowsToRemove.length} дубликат(ов) в файле ${path.basename(filePath)}`
      ));
    } else {
      console.log(chalk.yellow(`Дубликаты не найдены в файле ${path.basename(filePath)}`));
    }
  } catch (processError) {
    console.error(chalk.red(`Ошибка при обработке файла ${path.basename(filePath)}: ${processError.message}`));
  }
}

// Функция для удаления дубликатов во всех файлах
async function removeDuplicatesInAllFiles() {
  const files = fs.readdirSync(directoryPath);
  for (const file of files) {
    const filePath = path.join(directoryPath, file);
    const ext = path.extname(file).toLowerCase();
    if (ext === '.xlsx' || ext === '.xls') {
      await removeDuplicatesInFile(filePath);
    }
  }
}

// Функция для обработки пар файлов
async function processFiles() {
  await removeDuplicatesInAllFiles();

  for (const filePair of filePairs) {
    const sourceFilePath = path.join(directoryPath, filePair.sourceFileName);
    const targetFilePath = path.join(directoryPath, filePair.targetFileName);

    const sourceFileExists = fs.existsSync(sourceFilePath);
    const targetFileExists = fs.existsSync(targetFilePath);

    if (sourceFileExists && targetFileExists) {
      console.log(
        `Обработка файлов: ${filePair.sourceFileName} и ${filePair.targetFileName}`
      );

      // Чтение исходного файла
      const sourceWorkbook = new ExcelJS.Workbook();
      try {
        await sourceWorkbook.xlsx.readFile(sourceFilePath);
      } catch (err) {
        console.error(chalk.red(`Не удалось прочитать исходный файл ${filePair.sourceFileName}: ${err.message}`));
        continue; // Переход к следующей паре файлов
      }
      const sourceWorksheet = sourceWorkbook.getWorksheet(1);

      if (!sourceWorksheet) {
        console.error(chalk.red(`В исходном файле ${filePair.sourceFileName} не найден лист с индексом 1.`));
        continue;
      }

      // Чтение целевого файла
      const targetWorkbook = new ExcelJS.Workbook();
      try {
        await targetWorkbook.xlsx.readFile(targetFilePath);
      } catch (err) {
        console.error(chalk.red(`Не удалось прочитать целевой файл ${filePair.targetFileName}: ${err.message}`));
        continue;
      }
      const targetWorksheet = targetWorkbook.getWorksheet(1);

      if (!targetWorksheet) {
        console.error(chalk.red(`В целевом файле ${filePair.targetFileName} не найден лист с индексом 1.`));
        continue;
      }

      // Получение индексов столбцов
      const sourceHeaderRow = sourceWorksheet.getRow(1);
      const sourceColumnIndices = getColumnIndices(
        sourceHeaderRow,
        filePair.sourceColumns
      );

      const targetHeaderRow = targetWorksheet.getRow(1);
      const targetColumnIndices = getColumnIndices(
        targetHeaderRow,
        filePair.targetColumns
      );

      // Извлечение данных из исходного файла
      const dataToAppend = [];
      sourceWorksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
        if (rowNumber === 1) return; // Пропустить заголовок
        const dataRow = {};
        filePair.sourceColumns.forEach((col) => {
          const colIndex = sourceColumnIndices[col];
          dataRow[col] = row.getCell(colIndex).value;
        });
        dataToAppend.push(dataRow);
      });

      // Отображение данных на целевые столбцы
      const mappedData = dataToAppend.map((dataRow) => {
        const mappedRow = {};
        filePair.sourceColumns.forEach((sourceCol, index) => {
          const targetCol = filePair.targetColumns[index];
          mappedRow[targetCol] = dataRow[sourceCol];
        });
        return mappedRow;
      });

      // Удаление дубликатов
      const existingRowsSet = new Set();
      targetWorksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
        if (rowNumber === 1) return;
        const keyValues = filePair.keyColumns
          .map((col) => {
            const colIndex = targetColumnIndices[col];
            return row.getCell(colIndex).value;
          })
          .join('||');
        existingRowsSet.add(keyValues);
      });

      let newRowsAdded = 0;
      mappedData.forEach((dataRow) => {
        const keyValues = filePair.keyColumns
          .map((col) => dataRow[col])
          .join('||');
        if (!existingRowsSet.has(keyValues)) {
          existingRowsSet.add(keyValues);
          const newRow = targetWorksheet.addRow();
          Object.entries(dataRow).forEach(([header, value]) => {
            const colIndex = targetColumnIndices[header];
            newRow.getCell(colIndex).value = value;
          });
          newRowsAdded++;
        }
      });

      console.log(
        `Добавлено ${newRowsAdded} новых строк в ${filePair.targetFileName}`
      );

      // Сохранение и удаление исходного файла
      try {
        await targetWorkbook.xlsx.writeFile(targetFilePath);
        fs.unlinkSync(sourceFilePath);
        console.log(`Удален файл ${filePair.sourceFileName}`);
      } catch (err) {
        console.error(chalk.red(`Ошибка при сохранении или удалении файлов: ${err.message}`));
      }
    } else if (sourceFileExists) {
      console.log(chalk.yellow(`Только исходный файл существует: ${filePair.sourceFileName}`));
    } else if (targetFileExists) {
      console.log(chalk.yellow(`Только целевой файл существует: ${filePair.targetFileName}`));
    } else {
      console.log(
        `Файлы не найдены: ${filePair.sourceFileName} и ${filePair.targetFileName}`
      );
    }
  }
}

// Запуск процесса обработки файлов с обработкой ошибок
processFiles().catch((error) => {
  console.error('Произошла ошибка:', error);
});