Arcane.Excel
Ler e gravar planilhas .xlsx sem dependência externa.
Um .xlsx é um ZIP de arquivos XML. O Arcane.Excel escreve e lê esse formato usando só a biblioteca padrão do Python — o arquivo abre no Excel, no LibreOffice e no Google Sheets, e é lido de volta por openpyxl e pandas.
O caminho curto#
adopt Arcane.Excel as Xls
vendas := [
{"produto": "Martelo", "qtd": 12, "preco": 89.9},
{"produto": "Bigorna", "qtd": 3, "preco": 450.0}
]
Xls.quick("vendas.xlsx", vendas, "Vendas")Quando os dados são vaults, o cabeçalho sai das chaves — em negrito, com a primeira linha congelada e a largura ajustada ao conteúdo. Sem isso, a planilha abre com colunas de ####.
Ler#
livro := Xls.read("vendas.xlsx")
Xls.sheets(livro) // ["Vendas"]
Xls.dims(livro, "Vendas") // {linhas: 3, colunas: 3, celulas: 9}
Xls.rows(livro, "Vendas") // lista de listas
Xls.records(livro, "Vendas") // lista de vaults, pelo cabeçalho
Xls.column(livro, "Vendas", "qtd") // [12, 3]
Xls.get(Xls.sheet(livro, "Vendas"), "B2") // 12column aceita o título ou a letra. O título vence: numa planilha com uma coluna chamada B, pedir "B" traz essa coluna, não a segunda.
Os tipos sobrevivem#
| Grava | Volta como |
|---|---|
42 | Integer |
89.9 | Float |
yes / no | Boolean |
| uma data | data (o formato do Excel é um número; o módulo reconhece) |
| texto | String |
void | célula vazia — e ela não ocupa espaço |
Um número que chega como texto abre a planilha com tudo alinhado à esquerda e nada soma. Por isso from_csv converte o que parece número.
Montar com cuidado#
livro := Xls.new()
aba := Xls.sheet(livro, "Vendas", vendas)
Xls.set(aba, "D1", "total")
cycle i from 2 to 3:
Xls.formula(aba, $"D{i}", $"B{i}*C{i}")
Xls.set(aba, "A4", "SOMA")
Xls.formula(aba, "D4", "SUM(D2:D3)")
Xls.bold_row(aba, 3)
Xls.freeze(aba, "A2")
Xls.width(aba, "A", 28)
Xls.save(livro, "relatorio.xlsx")Fórmulas#
Uma fórmula não é calculada aqui: é gravada, e o Excel a resolve ao abrir. É o que se quer num relatório — quem receber pode mexer nos números e ver o total mudar sozinho. Um valor calculado em DataForge seria um número morto.
Xls.get_formula(aba, "D4") // "SUM(D2:D3)"
Xls.formulas(aba) // {"D2": "B2*C2", "D4": "SUM(D2:D3)"}Por isso a coluna de fórmulas volta vazia em rows: não há valor gravado, e isso não é um bug.
Converter#
Xls.from_csv("dados.csv") // CSV → livro
Xls.to_csv(livro, "saida.csv") // livro → CSV
Xls.to_frame(livro, "Vendas") // livro → frame do Analytics
Xls.from_frame(tabela, "Dados") // frame → livroto_frame é a ponte para o Arcane.Analytics: a planilha vira uma tabela que describe, correlation e group_by entendem.
Planilha esparsa#
aba := Xls.sheet(livro, "T")
Xls.set(aba, "A1", "canto")
Xls.set(aba, "Z100", "outro canto")
// duas células ocupadas, não 2.600As células ficam num mapa esparso. Escrever em Z100 não materializa 100 linhas vazias — nem no programa, nem no arquivo.
Endereços#
Xls.addr(0, 0) // "A1"
Xls.addr(6, 1) // "B7"
Xls.parse_addr("B7") // {linha: 6, coluna: 1}
Xls.col_letter(26) // "AA"Nos endereços em texto ("B7") a contagem começa em 1, como no Excel. Em Xls.cell(aba, linha, coluna) começa em 0, como no resto da linguagem.
As 29 funções#
| Grupo | Funções |
|---|---|
| livro | new, read, save, sheets, sheet, drop_sheet, quick |
| células | get, set, cell, formula, get_formula, formulas, append |
| leitura | rows, records, column, dims |
| formatação | width, bold_row, freeze, autofit |
| conversão | from_csv, to_csv, to_frame, from_frame |
| endereços | addr, parse_addr, col_letter |
O que ele não faz#
Não calcula fórmulas, não desenha gráficos, não lê .xls antigo (o formato binário anterior a 2007) e não faz tabela dinâmica. Cores e bordas se limitam ao negrito do cabeçalho. Para o que ele faz — levar dados para dentro e para fora de uma planilha — está completo.