Tres grupos de ajustes de hoja de cálculo no tienen nada que ver con los valores de las celdas y todo que ver con cómo se comporta el archivo una vez que sale de su código. La protección de hoja decide qué celdas puede editar un usuario después de que usted entregue el libro de trabajo. La configuración de página fija la orientación, el tamaño de papel y los márgenes. Los ajustes de impresión (filas de título repetidas, escalado y saltos de página manuales) controlan cómo aterriza en papel una cuadrícula de longitud arbitraria. Ninguno de los tres aparece cuando se echa un vistazo a los datos en un visor, y los tres fallan silenciosamente sobre el terreno cuando están mal. HotXLS, una biblioteca nativa de hoja de cálculo para Delphi y C++Builder, expone la superficie completa para .xls y .xlsx, lo que significa que también reproduce cada regla contraintuitiva de Excel incorporada en esa superficie
La primera de esas reglas hace tropezar a casi todo el mundo la primera vez que protege una hoja generada. Llame a Protect y de repente nadie puede escribir en ninguna celda, incluidas las columnas de entrada alrededor de las cuales construyó el libro de trabajo. Nada en su código tocó esas columnas, y esa es exactamente la razón por la que ocurre
Toda celda nace bloqueada
ECMA-376 define locked como parte del registro de formato de una celda, no como una propiedad de la protección en sí, y su valor por defecto es true. La protección de hoja es simplemente el interruptor que hace exigible el indicador. Así que toda la cuadrícula lleva un indicador de bloqueo desde el momento en que existe, latente, y la llamada a Protect los activa todos a la vez. La solución es fijar el orden de forma deliberada: construya el diseño, desbloquee explícitamente los rangos que los usuarios deben editar, y proteja al final
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Timesheet');
// ... aquí se escriben la fila de cabecera, la columna de nombres y las fórmulas de tarifa ...
Sheet.Range['B2:B50'].SetLocked(False); // aquí el personal escribe las horas
Sheet.Range['F2:F50'].SetFormulaHidden(True); // mantiene privado el cálculo de la tarifa
Sheet.Protect('review-2026'); // ahora los indicadores de bloqueo surten efecto
Book.SaveAs('timesheet.xlsx');
finally
Book.Free;
end;
SetFormulaHidden hace algo distinto y fácil de pasar por alto: mientras la protección está activa, la celda sigue mostrando su valor calculado, pero la barra de fórmulas no muestra nada. Eso importa cuando una fórmula incorpora tarifas de facturación, márgenes, o pesos de puntuación que preferiría no entregar a cada destinatario que haga clic en un total. En la fachada XLS la misma intención se expresa por rango mediante IXLSRange.Locked y FormulaHidden. La hoja de cálculo ahí también lleva quince indicadores Allow* (AllowSort, AllowAutoFilter, AllowFormatCells, y el resto), de modo que una hoja protegida todavía puede ordenarse y filtrarse en lugar de quedar congelada como una pieza sellada
Qué protege realmente la contraseña de protección
Ambos formatos almacenan la contraseña de protección de hoja y de libro de trabajo como un hash heredado de 4 dígitos hexadecimales. Dieciséis bits significa que innumerables cadenas colisionan con cualquier contraseña dada, y las herramientas de eliminación están a una búsqueda de distancia. Trate la protección como un cinturón de seguridad contra ediciones accidentales, no como control de acceso. Es la herramienta adecuada para impedir que los revisores escriban sobre la columna de fórmulas, y la herramienta equivocada para cualquier cosa que involucre la palabra confidencial
Un nivel más arriba, ProtectWorkbook en la fachada XLSX bloquea la estructura del libro de trabajo, lo que impide añadir, renombrar, eliminar o reordenar hojas. Actívelo siempre que la lista de hojas sea en sí misma un contrato con un analizador posterior que indexe las hojas por nombre o posición. Una hoja renombrada rompe la importación en el otro extremo con la misma certeza que una columna eliminada. La fachada XLS refleja esa jerarquía con TXLSWorkbook.Protect a nivel de libro de trabajo y llamadas Protect por hoja, más una propiedad isProtected para el código que necesita inspeccionar un archivo heredado antes de modificar nada
Cuando el requisito es confidencialidad real, el mecanismo cambia por completo. SaveAsEncrypted produce un paquete cifrado con AES bajo el esquema ECMA-376 Standard Encryption, cubierto en profundidad en la guía de salida XLSX protegida con AES, y la fachada XLS heredada escribe y lee archivos .xls cifrados con RC4 mediante EncryptionPassword y la sobrecarga con contraseña de Open. La diferencia no es académica. Una hoja protegida viaja en texto claro, de modo que cualquier herramienta de zip puede leer sus valores de celda, mientras que un paquete cifrado es ilegible sin la contraseña. Una línea de auditoría que dice "el archivo de nóminas debe protegerse" casi siempre significa cifrado, sea cual sea el vocabulario que use
La configuración de página forma parte del contrato del documento
El comportamiento de impresión es invisible en pantalla, razón por la cual se distribuye roto con tanta frecuencia. En el momento en que un cliente imprime el libro de trabajo, o lo exporta a PDF para un auditor, los márgenes, el escalado y los títulos repetidos se convierten en requisitos funcionales que nadie probó. En la fachada XLSX estos ajustes cuelgan directamente de la hoja de cálculo:
Sheet.PageLandscape := True;
Sheet.PaperSize := xlsxPaperA4;
Sheet.SetPageMargins(0.5, 0.5, 0.75, 0.75, 0.3, 0.3);
Sheet.CenterHeader := 'Monthly Timesheet';
Sheet.RightFooter := 'Page &P of &N';
Sheet.PrintArea := '$A$1:$F$60'; // referencia desnuda: aquí no hay nombre de hoja
Sheet.PrintTitleRows := '$1:$1'; // la fila de cabecera se repite en cada página
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // crece hacia abajo a medida que crecen los datos
Sheet.PrintGridlines := False;
Dos de esas líneas esconden trampas. Las cadenas de cabecera y pie usan los códigos de formato de Excel: &P para la página actual, &N para el recuento total, con &L, &C, y &R para dirigirse explícitamente a las tres secciones. La otra trampa es PrintArea, que toma a propósito una referencia de celda desnuda. HotXLS la almacena sin cualificar y antepone el nombre de la hoja cuando escribe el archivo, así que pasar usted mismo 'Timesheet!$A$1:$F$60' produce una referencia doblemente cualificada y mal formada. La misma precaución se aplica un nivel más abajo: las áreas de impresión y los títulos de impresión se persisten como los nombres definidos integrados _xlnm.Print_Area y _xlnm.Print_Titles, así que nunca añada entradas _xlnm.* a mano mediante DefinedNames, o los dos mecanismos se disputarán la misma ranura
Escalado que sobrevive a los volúmenes de datos de producción
La combinación FitToWidth := 1 con FitToHeight := 0 se lee como "ajustar siempre las columnas a una página, y luego usar tantas páginas hacia abajo como necesiten los datos", y es el valor por defecto correcto para cualquier informe cuyo número de filas varíe. La trampa es ajustar un porcentaje fijo o un par de ajuste a página contra un archivo de prueba de treinta filas: dé las mismas opciones a seiscientas filas de producción y la salida o bien explota en docenas de páginas recortadas o se encoge por debajo de la legibilidad. Escale el ancho, deje crecer el largo, y repita la fila de cabecera mediante PrintTitleRows para que la página diecisiete siga siendo legible por sí sola
Los saltos manuales siguen la misma disciplina de regeneración que todo lo demás en un libro de trabajo generado. AddRowBreak(BeforeRow) inicia una página nueva antes de un límite de sección, pero cuando el generador se vuelve a ejecutar y las filas se desplazan, un salto obsoleto acaba en mitad de la tabla. Llame primero a ClearAllPageBreaks, y luego vuelva a añadir los saltos calculados a partir de los propios contadores de fila del generador en lugar de parchear posiciones antiguas. En la fachada XLS los controles equivalentes viven en Sheet.PageSetup (orientación, tamaño de papel, márgenes, cadenas de cabecera y pie, ajuste a páginas), con RepeatRows y RepeatColumns cubriendo los títulos de impresión
Comprobar el resultado antes de que lo haga un cliente
Los errores de protección y de impresión comparten una propiedad: son triviales de verificar a mano y casi nunca se verifican. Abra el archivo generado en Excel y dedíquele noventa segundos. Escriba en una celda de entrada y confirme que acepta la pulsación; escriba en una celda bloqueada y confirme que aparece el aviso de protección; compruebe que una fórmula oculta deja la barra de fórmulas en blanco. Luego ejecute Vista previa de impresión contra un conjunto de datos de tamaño de producción, no una muestra de treinta filas, y lea el número de páginas, la fila de título repetida, y la numeración del pie. La vista previa es el paso que se paga solo, porque la geometría de impresión depende de ajustes sin representación en pantalla, y salvo una impresora física es el único lugar donde un error de escalado llega a hacerse visible
Un último ajuste completa la revisión. FreezePane(ACol, ARow) mantiene el bloque de cabecera a la vista mientras un revisor se desplaza. Eso es comportamiento en pantalla más que comportamiento de impresión, pero un revisor juzga la entrega completa de una sola vez. Y un libro de trabajo que empieza su vida como un diseño mantenido por un diseñador obtiene gran parte de esto gratis: el flujo de generación de informes basados en plantilla mantiene la configuración de página en la plantilla, donde una persona la ajustó contra una impresora real, y deja que el código rellene los datos y vuelva a aplicar la protección una vez que el diseño se asienta
HotXLS es una biblioteca nativa de hoja de cálculo en Object Pascal para Delphi y C++Builder; la referencia completa de la API de protección y configuración de página está en la página de producto de HotXLS Delphi Component