Я пытаюсь создать отчет, в котором часть верхнего и нижнего колонтитула жестко закодирована в файле шаблона 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);
});
Если я смогу добиться слияния ячеек, это сэкономит много времени и усилий, поскольку я могу использовать тот же подход для других отчетов с другими верхними и нижними колонтитулами. Помогите пожалуйста разобраться в проблеме или/и что я делаю не так
заранее спасибо





Я нашел обходной путь для этой проблемы.
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);
});
});