O HotXLS cria objetos de câmera do Excel em planilhas XLSX a partir do Delphi por meio de AddCamera. Um objeto de câmera é uma imagem permanentemente vinculada a um intervalo de células: o Excel a renderiza novamente a partir do intervalo de origem toda vez que a pasta de trabalho é aberta ou a origem muda, de modo que um painel pode mostrar uma visão ativa de uma tabela que fica em outra planilha, em qualquer tamanho, girada se você quiser
O recurso existe no Excel como a ferramenta Câmera, um botão que a maioria dos usuários nunca viu porque não fica na faixa de opções por padrão. Ele resolve um problema real de painel melhor do que as alternativas: um intervalo copiado fica obsoleto, um gráfico não consegue mostrar conteúdo de célula arbitrário, e uma imagem vinculada colada à mão não pode ser gerada por código. Um objeto de câmera é a única construção que é ao mesmo tempo ativa e arbitrária
Onde isso está documentado, e por que isso importa?
A especificação principal de planilha não descreve objetos de câmera; eles são tratados como um detalhe de implementação. A descrição autorizada fica na documentação de marcação de desenho, sob o título Camera Tool, e saber disso poupa uma tarde inteira de busca no documento errado
Estruturalmente, um objeto de câmera é um elemento de imagem comum cujas propriedades não visuais de imagem carregam uma lista de extensões. A extensão é identificada por um GUID fixo, e dentro dela um elemento do namespace de desenho de 2010 registra duas coisas: o intervalo de origem como uma referência absoluta no estilo A1, opcionalmente qualificada por planilha, e um identificador de forma. Tudo o mais na imagem é comum
Criando uma
Existem duas sobrecargas porque duas formas de nomear um intervalo são convenientes. A forma textual recebe a referência exatamente como será armazenada, o que é o que você quer para uma origem entre planilhas. A forma de coordenadas recebe quatro coordenadas de célula na mesma planilha e monta a referência absoluta para você:
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];
// Visão ativa de Data!$B$2:$D$4, posicionada sobre B10:F20 no painel
Cam := Dashboard.AddCamera('Data!$B$2:$D$4', 10, 2, 20, 6);
// A caixa de posicionamento usa por padrão as colunas de 64 px e
// linhas de 20 px do próprio Excel; ajuste o tamanho desenhado em
// EMU depois, se necessário
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;
O objeto retornado é um objeto de imagem normal com uma propriedade extra, CameraRange, que fica não vazia exatamente quando a imagem é uma câmera. É também assim que você detecta câmeras em uma pasta de trabalho que não criou: enumere as imagens e verifique a propriedade
Por que a imagem de espaço reservado não precisa ser real?
Toda imagem em um pacote XLSX precisa de uma parte de imagem, e um objeto de câmera não é exceção. Mas o Excel ignora essa imagem: ao abrir, ele renderiza novamente o intervalo vinculado e pinta o resultado. Os bytes incorporados existem puramente como um cache de exibição para ferramentas que não implementam o comportamento de câmera
Esse fato remove um subsistema inteiro da implementação. Não há necessidade de rasterizar o intervalo de origem, não há necessidade de um motor de renderização para produzir o instantâneo, e não há risco de a imagem em cache discordar da imagem ativa no Excel. O HotXLS grava um metafile de espaço reservado mínimo — um registro de cabeçalho e um registro de fim de arquivo, 108 bytes no total — o que mantém o pacote estruturalmente completo e não custa nada
Uma consequência a planejar: um visualizador que renderiza XLSX sem implementar objetos de câmera mostra o espaço reservado, que fica em branco. Se suas pastas de trabalho são consumidas por uma ferramenta dessas, um objeto de câmera é a construção errada, e uma imagem renderizada do intervalo é a certa
A conversão de unidades que é fácil de errar
A geometria de desenho no Open XML é medida em Unidades Métricas Inglesas, em que uma polegada equivale a 914.400 EMU e um centímetro a 360.000. Os cabeçalhos de metafile, no entanto, registram seu quadro em unidades de 0,01 milímetro. A conversão entre eles é uma divisão por 360
Vale a pena nomear isso porque o erro é silencioso. Converter passando por pixels a 96 DPI em vez disso — multiplicando por 2540 e dividindo por 9525 — produz um valor 96 vezes grande demais, e nada rejeita isso: o pacote é válido, a imagem é posicionada corretamente pela âncora, e apenas o quadro declarado do metafile é um disparate. O modelo de EMU e seu comportamento de arredondamento são abordados em geometria de imagem, unidades EMU e escala
Ida e volta em uma pasta de trabalho que já tem câmeras
Abrir e salvar uma pasta de trabalho preserva os objetos de câmera, incluindo o elemento de extensão e sua referência de intervalo. Isso importa mais do que criá-los: a maioria das pastas de trabalho com objetos de câmera foi feita no Excel por um analista, e uma biblioteca que converte silenciosamente esses objetos em imagens comuns ao salvar destruiu o comportamento ativo com o qual o analista contava
// Audita quais imagens são câmeras e para onde apontam
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]));
Quando você gera painéis programaticamente, a auditoria também é o teste de regressão: depois de um ciclo de salvar e reabrir, o mesmo número de câmeras precisa apontar para os mesmos intervalos. O tratamento geral de imagens e desenhos, incluindo o modelo de ancoragem que os posiciona, é abordado em gráficos, imagens e desenhos
Quando uma câmera supera as alternativas
Use um objeto de câmera quando a mesma tabela ativa precisa aparecer em várias planilhas em tamanhos diferentes, quando um layout de impressão precisa de uma região de uma planilha composta ao lado de regiões de outras, ou quando um bloco de resumo deve acompanhar edições feitas em outro lugar sem uma fórmula vinculando cada célula individualmente
Prefira fórmulas comuns quando o alvo for um punhado de células, porque uma fórmula entre planilhas é mais simples e toda ferramenta a entende. Prefira um gráfico quando os dados forem genuinamente uma série, e não um bloco formatado. E prefira uma imagem renderizada quando a pasta de trabalho for consumida por ferramentas além do Excel, ou quando o instantâneo não puder mudar após a entrega — um relatório arquivado não deveria ser ativo
Uma observação de layout da prática: uma câmera mostra o intervalo de origem exatamente como formatado, incluindo células mescladas, formatos condicionais e larguras de coluna. Obter um bloco de painel com aparência limpa, portanto, começa formatando o intervalo de origem como se ele fosse o resultado final, a mesma disciplina descrita em células mescladas e layout de template de relatório
Objetos de câmera, desenhos e o gravador de pacote XLSX por trás deles vêm em uma única biblioteca para Delphi e C++Builder; a lista completa de recursos está na página do componente de planilha Delphi HotXLS