From 6a56356c3989e46968c777e5afb3cc9a244a9295 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 17 Mar 2026 11:06:52 -0600 Subject: [PATCH] Add Excel processing functionality with merge pattern application - Introduced `index.ts` to read an Excel file and apply merge patterns to specified ranges. - Created `lib.ts` with utility functions for column number conversion and merge pattern application. - Updated execution counts in `carbone.ipynb` to reflect the new code structure. --- notebooks/carbone.ipynb | 16 +++++------ notebooks/excel/index.ts | 43 ++++++++++++++++++++++++++++++ notebooks/excel/lib.ts | 57 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 notebooks/excel/index.ts create mode 100644 notebooks/excel/lib.ts diff --git a/notebooks/carbone.ipynb b/notebooks/carbone.ipynb index b940d84..1d2bf4a 100644 --- a/notebooks/carbone.ipynb +++ b/notebooks/carbone.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "76919cba", "metadata": {}, "outputs": [], @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "20231839", "metadata": {}, "outputs": [], @@ -68,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "9950c1f7", "metadata": {}, "outputs": [], @@ -400,7 +400,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "95b24436", "metadata": {}, "outputs": [ @@ -489,7 +489,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "caf8bc20", "metadata": {}, "outputs": [ @@ -520,7 +520,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "id": "929883b9", "metadata": {}, "outputs": [], @@ -575,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "id": "29cdb42f", "metadata": {}, "outputs": [], @@ -640,7 +640,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "id": "18fec251", "metadata": {}, "outputs": [ diff --git a/notebooks/excel/index.ts b/notebooks/excel/index.ts new file mode 100644 index 0000000..9c793b2 --- /dev/null +++ b/notebooks/excel/index.ts @@ -0,0 +1,43 @@ +import ExcelJS from "exceljs"; +import { applyMergePattern } from "./lib"; + +/* const inputFile = Bun.file("mapa.xlsx"); +const inputBuffer = await inputFile.arrayBuffer(); + +const workbook = new ExcelJS.Workbook(); +await workbook.xlsx.load(inputBuffer); */ + +const workbook = new ExcelJS.Workbook(); +await workbook.xlsx.readFile("mapa.xlsx"); + +const sheetName = 'RÍGIDO-Anexo 2 (A)' +const sheet = workbook.getWorksheet(sheetName) +if (!sheet) { + throw new Error(`Workbook has no sheet named: ${sheetName}`); +} + +const CICLOS = 9; +const matrizAsignaturas = { + startColumns: ["C", "I", "O", "U", "AA"], + firstStartRow: 8, + mergeWidthInColumns: 5, + mergeHeightInRows: 3, + mergeBlockCount: CICLOS, + rowStepBetweenBlocks: 14 - 8, +} as const; +const semestres = { + startColumns: ["A"], + firstStartRow: 7, + mergeWidthInColumns: 1, + mergeHeightInRows: 5, + mergeBlockCount: CICLOS, + rowStepBetweenBlocks: 13 - 7, +} as const; + +applyMergePattern(sheet, matrizAsignaturas); +applyMergePattern(sheet, semestres); + +const outputBuffer = await workbook.xlsx.writeBuffer(); +await Bun.write("excel2.xlsx", outputBuffer); + +const end = Bun.nanoseconds(); \ No newline at end of file diff --git a/notebooks/excel/lib.ts b/notebooks/excel/lib.ts new file mode 100644 index 0000000..b11834b --- /dev/null +++ b/notebooks/excel/lib.ts @@ -0,0 +1,57 @@ +import { type Worksheet } from "exceljs"; + + +/** + * Converts an Excel column label to a 1-based number. + * Example: A -> 1, Z -> 26, AA -> 27 + */ +function columnToNumber(label: string): number { + let n = 0; + + for (let i = 0; i < label.length; i++) { + n = n * 26 + label.charCodeAt(i) - 64; + } + + return n; +} + +/** + * Generates merge ranges like: + * C8:G10, I8:M10, ... + * then C14:G16, I14:M16, ... + */ +type MergeRangePattern = { + startColumns: readonly string[]; + firstStartRow: number; + mergeWidthInColumns: number; + mergeHeightInRows: number; + mergeBlockCount: number; + rowStepBetweenBlocks: number; +}; + +export function applyMergePattern(sheet: Worksheet, config: MergeRangePattern) { + + const { + startColumns, + firstStartRow, + mergeWidthInColumns, + mergeHeightInRows, + mergeBlockCount, + rowStepBetweenBlocks + } = config; + + for (let block = 0; block < mergeBlockCount; block++) { + + const rowStart = firstStartRow + block * rowStepBetweenBlocks; + const rowEnd = rowStart + mergeHeightInRows - 1; + + for (const column of startColumns) { + + const colStart = columnToNumber(column); + const colEnd = colStart + mergeWidthInColumns - 1; + + sheet.mergeCells(rowStart, colStart, rowEnd, colEnd); + + } + } +} \ No newline at end of file