Вставка строк в Excel JS дает ошибку при объединении двух ячеек

Я пытаюсь создать отчет, в котором часть верхнего и нижнего колонтитула жестко закодирована в файле шаблона excel, и я пытаюсь заполнить данные таблицы, которые находятся между нижним колонтитулом и заголовком.

На приведенном выше снимке экрана я пытаюсь заполнить данные между 15 и 16, что может быть легко достигнуто с помощью Excel JS. Но проблема возникает при попытке объединить ячейки из 16 и 17 строк вновь добавленных, это дает ошибку ниже!

Например: - worksheet.mergeCells(A16:A17); // Выдает: - Ошибка: невозможно объединить уже объединенные ячейки

Ошибка: невозможно объединить уже объединенные ячейки

Скриншот ниже - это то, чего я пытаюсь достичь. В основном один цикл добавит две строки и, кроме двух столбцов, мне нужно объединить все остальные ячейки по вертикали.

Ниже приведен код, который я написал. Я могу вставлять данные между строками и получать выходной файл, но при попытке объединить ячейки я получаю ту же ошибку. Также попытался добавить пустую строку и объединить перед вставкой данных в строку, но это также не сработало.

const filepath = path.join(__dirname, "./excel/template.xlsx");
const workbook = new Excel.Workbook();
workbook.xlsx.readFile(filepath).then(function () {
var worksheet = workbook.getWorksheet("Sheet1");

let row = 16;
let count = 1;
if (fitupData.length) {
    var borderStyles = {
    top: { style: "thin" },
    left: { style: "thin" },
    bottom: { style: "thin" },
    right: { style: "thin" },
    };

    fitupData.forEach((item) => {
        let firstRow = worksheet.insertRow(row, []);
        let secondRow = worksheet.insertRow(row, []);

        firstRow.border = borderStyles;
        firstRow.alignment = { horizontal: "center" };


        worksheet.getCell(`J${row}`).value = item.A2;
        worksheet.getCell(`K${row}`).value = item.B2;

        secondRow.values = [
            count,
            item.v1,
            item.v2,
            item.v3,
            item.v4,
            item.v5,
            item.v6,
            item.v7,
            item.v8,
            item.A1,
            item.B1,
            "Accepted",
            "-",
            item.v11,
            "-",
            "-",
            item.v12,
        ];


        // Merging cells dynamically
        for (let i = 65; i <= 81; i++) {
            //A to J
            let col = String.fromCharCode(i);
            if (["J", "K"].includes(col)) continue;
            worksheet.mergeCells(`${col}${row}:${col}${row + 1}`);
        }

        row = row + 2;
        count++;
    });
}

const fileName = path.join(__dirname, "./excel/Report.xlsx");
workbook.xlsx
    .writeFile(fileName)
    .then(() => {
    resolve(fileName);
    })
    .catch((err) => {
    console.info(err);
    });

Если я смогу добиться слияния ячеек, это сэкономит много времени и усилий, поскольку я могу использовать тот же подход для других отчетов с другими верхними и нижними колонтитулами. Помогите пожалуйста разобраться в проблеме или/и что я делаю не так

заранее спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
160
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел обходной путь для этой проблемы.

const filepath = path.join(__dirname, "./excel/template.xlsx");
const workbook = new Excel.Workbook();

let exportWorkbook = new Excel.Workbook();

workbook.xlsx.readFile(filepath).then(function () {
  /** Get Sheet1 from selected template */
  let worksheet = workbook.getWorksheet("Sheet1");

  /** Create new sheet Report */
  let exportSheet = exportWorkbook.addWorksheet("Report", {
    views: [{ showGridLines: false }],
  });

  /**Get header rows from template*/
  const header = worksheet.getRows(1, 15);
  /**Get Footer rows from template */
  const footer = worksheet.getRows(16, 8);

  /** Add Headers from Template to New WorkSheet */
  for (let index = 0; index < header.length; index++) {
    const element = header[index];
    let r = exportSheet.addRow([]);
    Object.assign(r, element);
  }

  let currentRow = 14;
  if (dataLength > 0) {
    for (let index = 0; index < dataLength; index++) {
      const item = fitupData[index];
      currentRow += 2;

      /** Add first row */
      exportSheet.addRow(
        [
          index + 1,
          item.V1,
          item.V2 || "D",
          item.V3 || "LN",
          item.V4 || "LC",
          item.V5 || "SP",
          item.V6 || "JN",
          item.V7 || "TK",
          item.V8 || "JT",
          item.A2 || "MG",
          item.A1 || "HN",
          "Acce",
          "-",
          item.V9 || "WPS",
          "-",
          "-",
          item.V10 || "TD",
        ],
        "i"
      );

      /** Add second row */
      exportSheet.addRow(
        [
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          item.A1 || "",
          item.A2 || "",
          "",
          "",
          "",
          "",
          "",
          "",
        ],
        "i"
      );

      /** Merge rows */
      exportSheet.mergeCells(`A${currentRow}:A${currentRow + 1}`);
      exportSheet.mergeCells(`B${currentRow}:B${currentRow + 1}`);
      exportSheet.mergeCells(`C${currentRow}:C${currentRow + 1}`);
      exportSheet.mergeCells(`D${currentRow}:D${currentRow + 1}`);
      exportSheet.mergeCells(`E${currentRow}:E${currentRow + 1}`);
      exportSheet.mergeCells(`F${currentRow}:F${currentRow + 1}`);
      exportSheet.mergeCells(`G${currentRow}:G${currentRow + 1}`);
      exportSheet.mergeCells(`H${currentRow}:H${currentRow + 1}`);
      exportSheet.mergeCells(`I${currentRow}:I${currentRow + 1}`);
      exportSheet.mergeCells(`L${currentRow}:L${currentRow + 1}`);
      exportSheet.mergeCells(`M${currentRow}:M${currentRow + 1}`);
      exportSheet.mergeCells(`N${currentRow}:N${currentRow + 1}`);
      exportSheet.mergeCells(`O${currentRow}:O${currentRow + 1}`);
      exportSheet.mergeCells(`P${currentRow}:P${currentRow + 1}`);
      exportSheet.mergeCells(`Q${currentRow}:Q${currentRow + 1}`);
    }
  }

  // Get all merge ranges
  const merges = worksheet.model.merges;

  // Fix for the solution
  for (let index = 0; index < footer.length; index++) {
    const footerRow = footer[index];
    const currentRowNum = footerRow.number;
    let newRow = exportSheet.addRow(footerRow.values, "i+");
    const newRowNum = newRow.number;

    //Apply Style
    footerRow.eachCell((cell, num) => {
      const newCell = newRow.getCell(num);
      newCell.style = cell.style;
    });

    // Get Merge Values of footer row
    const rowMerges = merges.filter((range) =>
      range.match(`\\w+${currentRowNum}:\\w+${currentRowNum}`)
    );

    // Apply merge range
    rowMerges
      .map((range) =>
        range.replace(new RegExp(`${currentRowNum}`, "g"), `${newRowNum}`)
      )
      .forEach((range) => exportSheet.mergeCells(range));
  }

  const fileName = path.join(__dirname, "./excel/Fitup-Report.xlsx");
  const pdfOutPut = path.join(__dirname, "./excel/Fitup-Report.pdf");
  /** Create Excel as per the WorkSheet data above */
  exportWorkbook.xlsx
    .writeFile(fileName)
    .then(async () => {
      await convert(fileName, pdfOutPut);
      resolve(pdfOutPut);
    })
    .catch((err) => {
      console.error(err);
      reject(err);
    });
});

Другие вопросы по теме