UNPKG

wordxml-builder

Version:

Librería TypeScript para construir documentos XML compatibles con Microsoft Word

220 lines (219 loc) 8.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TableBuilder = void 0; const paragraph_1 = require("./paragraph"); /** * Clase para construir tablas en formato XML compatible con Word */ class TableBuilder { /** * Crea una nueva instancia de TableBuilder * @param table - Estructura de la tabla a construir */ constructor(table) { this.table = table; } /** * Genera el XML de la tabla * @returns XML de la tabla como string */ toXML() { const tableStyle = this.generateTableStyle(); const grid = this.generateGrid(); const headers = this.generateHeaders(); const rows = this.generateRows(); return `<w:tbl>${tableStyle}${grid}${headers}${rows}</w:tbl>`; } /** * Genera el XML de los estilos de la tabla * @returns XML de los estilos */ generateTableStyle() { if (!this.table.style) return ''; const style = this.table.style; let styleXml = '<w:tblPr>'; // Ancho de la tabla if (style.width) { styleXml += `<w:tblW w:w="${style.width}" w:type="dxa"/>`; } // Alineación de la tabla if (style.alignment) { styleXml += `<w:jc w:val="${style.alignment}"/>`; } // Bordes de la tabla if (style.borders) { styleXml += '<w:tblBorders>'; if (style.borders.top) { styleXml += this.generateBorderXML('top', style.borders.top); } if (style.borders.right) { styleXml += this.generateBorderXML('right', style.borders.right); } if (style.borders.bottom) { styleXml += this.generateBorderXML('bottom', style.borders.bottom); } if (style.borders.left) { styleXml += this.generateBorderXML('left', style.borders.left); } if (style.borders.insideH) { styleXml += this.generateBorderXML('insideH', style.borders.insideH); } if (style.borders.insideV) { styleXml += this.generateBorderXML('insideV', style.borders.insideV); } styleXml += '</w:tblBorders>'; } // Espaciado entre celdas if (style.cellSpacing !== undefined) { styleXml += `<w:tblCellSpacing w:w="${style.cellSpacing}" w:type="dxa"/>`; } styleXml += '</w:tblPr>'; return styleXml; } /** * Genera el XML de la cuadrícula de la tabla * @returns XML de la cuadrícula */ generateGrid() { var _a; const columnCount = this.table.headers.length; let gridXml = '<w:tblGrid>'; // Distribuir el ancho total entre las columnas const columnWidth = ((_a = this.table.style) === null || _a === void 0 ? void 0 : _a.width) ? Math.floor(this.table.style.width / columnCount) : 1000; for (let i = 0; i < columnCount; i++) { gridXml += `<w:gridCol w:w="${columnWidth}"/>`; } gridXml += '</w:tblGrid>'; return gridXml; } /** * Genera el XML de los encabezados superiores * @returns XML de los encabezados */ generateHeaders() { let headersXml = '<w:tr>'; // Agregar celda vacía si hay cabeceras laterales if (this.table.leftHeaders && this.table.leftHeaders.length > 0) { headersXml += '<w:tc><w:p/></w:tc>'; } this.table.headers.forEach(header => { var _a; const cellStyle = header.style || ((_a = this.table.style) === null || _a === void 0 ? void 0 : _a.headerCellStyle); headersXml += this.generateCell(header, cellStyle); }); headersXml += '</w:tr>'; return headersXml; } /** * Genera el XML de las filas * @returns XML de las filas */ generateRows() { let rowsXml = ''; this.table.rows.forEach((row, rowIndex) => { var _a, _b; rowsXml += '<w:tr>'; // Agregar cabecera lateral si existe if (this.table.leftHeaders && this.table.leftHeaders[rowIndex]) { const leftHeaderStyle = this.table.leftHeaders[rowIndex].style || ((_a = this.table.style) === null || _a === void 0 ? void 0 : _a.leftHeaderCellStyle) || ((_b = this.table.style) === null || _b === void 0 ? void 0 : _b.headerCellStyle); rowsXml += this.generateCell(this.table.leftHeaders[rowIndex], leftHeaderStyle); } row.cells.forEach(cell => { var _a, _b; const cellStyle = cell.style || ((_a = row.style) === null || _a === void 0 ? void 0 : _a.cellStyle) || ((_b = this.table.style) === null || _b === void 0 ? void 0 : _b.cellStyle); rowsXml += this.generateCell(cell, cellStyle); }); rowsXml += '</w:tr>'; }); return rowsXml; } /** * Genera el XML de una celda * @param cell - Celda a generar * @param style - Estilo de la celda * @returns XML de la celda */ generateCell(cell, style) { let cellXml = '<w:tc>'; // Estilos de la celda if (style) { cellXml += this.generateCellStyle(style); } // Contenido de la celda const paragraph = new paragraph_1.Paragraph(cell.content, style === null || style === void 0 ? void 0 : style.paragraphStyle); cellXml += paragraph.toXML(); cellXml += '</w:tc>'; return cellXml; } /** * Genera el XML de los estilos de una celda * @param style - Estilo de la celda * @returns XML de los estilos */ generateCellStyle(style) { let styleXml = '<w:tcPr>'; // Ancho de la celda if (style.width) { styleXml += `<w:tcW w:w="${style.width}" w:type="dxa"/>`; } // Alineación vertical if (style.alignment) { styleXml += `<w:vAlign w:val="${style.alignment}"/>`; } // Dirección del texto if (style.textDirection) { styleXml += `<w:textDirection w:val="${style.textDirection}"/>`; } // Bordes if (style.borders) { styleXml += '<w:tcBorders>'; if (style.borders.top) { styleXml += this.generateBorderXML('top', style.borders.top); } if (style.borders.right) { styleXml += this.generateBorderXML('right', style.borders.right); } if (style.borders.bottom) { styleXml += this.generateBorderXML('bottom', style.borders.bottom); } if (style.borders.left) { styleXml += this.generateBorderXML('left', style.borders.left); } styleXml += '</w:tcBorders>'; } // Sombreado if (style.shading) { styleXml += '<w:shd'; styleXml += ` w:fill="${style.shading.fill}"`; if (style.shading.color) { styleXml += ` w:color="${style.shading.color}"`; } if (style.shading.val) { styleXml += ` w:val="${style.shading.val}"`; } styleXml += '/>'; } // Combinación de celdas if (style.verticalMerge) { styleXml += `<w:vMerge w:val="${style.verticalMerge}"/>`; } if (style.horizontalMerge) { styleXml += `<w:gridSpan w:val="${style.gridSpan || 2}"/>`; } styleXml += '</w:tcPr>'; return styleXml; } /** * Genera el XML de un borde * @param position - Posición del borde * @param border - Configuración del borde * @returns XML del borde */ generateBorderXML(position, border) { return `<w:${position} w:val="${border.style}" w:sz="${border.size}" w:color="${border.color}" w:space="${border.space}"/>`; } } exports.TableBuilder = TableBuilder;