Artículo técnico

Objetos cámara de Excel desde Delphi: capturas en vivo

HotXLS crea objetos cámara de Excel en hojas de cálculo XLSX desde Delphi mediante AddCamera. Un objeto cámara es una imagen enlazada de forma permanente a un rango de celdas: Excel la vuelve a renderizar desde el rango de origen cada vez que el libro se abre o el origen cambia, de modo que un dashboard puede mostrar una vista en vivo de una tabla que vive en otra hoja, en cualquier tamaño, e incluso rotada si usted lo desea

La función existe en Excel como la herramienta Cámara, un botón que la mayoría de los usuarios nunca ha visto porque no aparece en la cinta de opciones por defecto. Resuelve un problema real de dashboards mejor que las alternativas: un rango copiado se queda desactualizado, un gráfico no puede mostrar contenido de celda arbitrario, y una imagen enlazada pegada a mano no se puede generar por código. Un objeto cámara es la única construcción que es a la vez en vivo y arbitraria

Objeto cámara de HotXLS creado desde Delphi: una imagen en vivo de Data!$B$2:$D$4 colocada en una hoja de dashboard que Excel vuelve a renderizar al abrir y en cada edición del origen
Un objeto cámara permanece enlazado de forma permanente a su rango de origen, de modo que Excel vuelve a renderizar la imagen al abrir y en cada edición, en cualquier tamaño y desde un rango ubicado en otra hoja

¿Dónde está documentado esto, y por qué importa?

La especificación principal de hojas de cálculo no describe los objetos cámara; se tratan como un detalle de implementación. La descripción autorizada vive en la documentación de marcado de dibujo, bajo el encabezado Camera Tool, y saber esto ahorra toda una tarde de buscar en el documento equivocado

Desde el punto de vista estructural, un objeto cámara es un elemento de imagen ordinario cuyas propiedades no visuales de imagen llevan una lista de extensión. La extensión se identifica mediante un GUID fijo, y dentro de ella un elemento del namespace de dibujo de 2010 registra dos cosas: el rango de origen como una referencia absoluta estilo A1, opcionalmente calificada por hoja, y un identificador de forma. Todo lo demás en la imagen es normal

Anatomía XLSX de un objeto cámara escrito por HotXLS desde Delphi: un elemento de imagen ordinario cuya lista de extensión lleva un elemento del namespace de dibujo de 2010 que registra el rango de origen absoluto y un identificador de forma
Desde el punto de vista estructural, una cámara es una imagen ordinaria más un elemento de extensión del namespace de dibujo de 2010, que registra el rango de origen absoluto estilo A1 y un identificador de forma

Crear un objeto cámara

Existen dos sobrecargas porque hay dos formas convenientes de nombrar un rango. La forma de texto toma la referencia exactamente como se almacenará, lo cual es lo que se quiere para un origen entre hojas. La forma de coordenadas toma cuatro coordenadas de celda en la misma hoja y construye la referencia absoluta por usted:

uses
  lxHandleX;

var
  Book: TXLSXWorkbook;
  Dashboard: TXLSXWorksheet;
  Cam: TXLSXImage;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open('reporting.xlsx') <> 1 then
      Exit;
    Dashboard := Book.Sheets[0];

    // Vista en vivo de Data!$B$2:$D$4, colocada sobre B10:F20 en el dashboard
    Cam := Dashboard.AddCamera('Data!$B$2:$D$4', 10, 2, 20, 6);

    // El cuadro de colocación usa por defecto las columnas de 64 px y
    // las filas de 20 px propias de Excel; ajuste el tamaño dibujado
    // en EMU después si es necesario
    Cam.WidthEMU := Round(12.5 * 914400 / 2.54);   // 12.5 cm
    Cam.HeightEMU := Round(6.0 * 914400 / 2.54);

    Book.SaveAs('reporting-dashboard.xlsx');
  finally
    Book.Free;
  end;
end;

El objeto devuelto es un objeto de imagen normal con una propiedad adicional, CameraRange, que no está vacía exactamente cuando la imagen es una cámara. Así es también como se detectan las cámaras en un libro que usted no creó: enumere las imágenes y revise la propiedad

¿Por qué la imagen de marcador de posición no necesita ser real?

Toda imagen dentro de un paquete XLSX necesita una parte de imagen, y un objeto cámara no es la excepción. Pero Excel ignora esa imagen: al cargar, vuelve a renderizar el rango enlazado y pinta el resultado. Los bytes embebidos existen únicamente como una caché de visualización para las herramientas que no implementan el comportamiento de cámara

Ese hecho elimina un subsistema completo de la implementación. No hay necesidad de rasterizar el rango de origen, no hay necesidad de un motor de renderizado que produzca la captura, y no hay riesgo de que la imagen en caché no coincida con la imagen en vivo en Excel. HotXLS escribe un metarchivo de marcador de posición mínimo — un registro de encabezado y un registro de fin de archivo, 108 bytes en total — que mantiene el paquete estructuralmente completo y no cuesta nada

Una consecuencia a tener en cuenta: un visor que renderiza XLSX sin implementar objetos cámara muestra el marcador de posición, que está en blanco. Si sus libros los consume una herramienta así, un objeto cámara es la construcción equivocada, y una imagen renderizada del rango es la correcta

Parte de imagen de marcador de posición de un objeto cámara de HotXLS: Excel vuelve a renderizar el rango enlazado al cargar e ignora el metarchivo de 108 bytes, mientras que los visores sin soporte de cámara muestran una imagen en blanco
Excel ignora los bytes embebidos y vuelve a renderizar el rango enlazado al cargar, así que HotXLS solo escribe un metarchivo de marcador de posición de 108 bytes, mientras que un visor sin soporte de cámara muestra el marcador de posición en blanco

La conversión de unidades que es fácil de hacer mal

La geometría de dibujo en Open XML se mide en English Metric Units (EMU), donde una pulgada equivale a 914,400 EMU y un centímetro a 360,000. Los encabezados de metarchivo, sin embargo, registran su marco en unidades de 0.01 milímetro. La conversión entre ambos es una división entre 360

Vale la pena nombrar esto porque el error es silencioso. Convertir en su lugar a través de píxeles a 96 DPI — multiplicando por 2540 y dividiendo entre 9525 — produce un valor 96 veces demasiado grande, y nada lo rechaza: el paquete es válido, la imagen se coloca correctamente mediante el ancla, y solo el marco declarado del metarchivo es un sinsentido. El modelo de EMU y su comportamiento de redondeo se cubren en geometría de imagen, unidades EMU y escalado

Preservar en el ciclo de ida y vuelta un libro que ya tiene cámaras

Abrir y guardar un libro preserva los objetos cámara, incluyendo el elemento de extensión y su referencia de rango. Esto importa más que crearlos: la mayoría de los libros con objetos cámara los hizo un analista en Excel, y una biblioteca que en silencio los convierte en imágenes ordinarias al guardar ha destruido el comportamiento en vivo del que dependía ese analista

// Auditar qué imágenes son cámaras y hacia dónde apuntan
for I := 0 to Sheet.Images.Count - 1 do
  if Sheet.Images[I].CameraRange <> '' then
    Writeln(Format('camera %d -> %s',
      [I, Sheet.Images[I].CameraRange]));

Cuando usted genera dashboards mediante programación, la auditoría también es la prueba de regresión: después de un ciclo de guardar y reabrir, la misma cantidad de cámaras debe apuntar a los mismos rangos. El manejo general de imágenes y dibujos, incluyendo el modelo de anclaje que las posiciona, se cubre en gráficos, imágenes y dibujos

Cuándo una cámara supera a las alternativas

Use un objeto cámara cuando la misma tabla en vivo deba aparecer en varias hojas con distintos tamaños, cuando un diseño de impresión necesite una región de una hoja compuesta junto con regiones de otras, o cuando un bloque de resumen deba seguir las ediciones hechas en otro lugar sin una fórmula que enlace cada celda individualmente

Prefiera fórmulas ordinarias cuando el objetivo sea un puñado de celdas, porque una fórmula entre hojas es más simple y toda herramienta la entiende. Prefiera un gráfico cuando los datos sean genuinamente una serie y no un bloque formateado. Y prefiera una imagen renderizada cuando el libro lo vayan a consumir herramientas distintas de Excel, o cuando la captura no deba cambiar después de la entrega — un informe archivado no debería estar en vivo

Una nota de diseño desde la práctica: una cámara muestra el rango de origen exactamente como está formateado, incluyendo celdas combinadas, formatos condicionales y anchos de columna. Por eso, conseguir un bloque de dashboard de aspecto limpio empieza por formatear el rango de origen como si fuera la salida terminada, la misma disciplina descrita en celdas combinadas y diseño de plantillas de informe

Los objetos cámara, los dibujos y el escritor de paquetes XLSX que los sostiene se entregan en una sola biblioteca para Delphi y C++Builder; la lista completa de funciones está en la página del componente de hoja de cálculo para Delphi de HotXLS