Exportar atributos para CSV
Script Groovy que despeja os atributos de um ramo num arquivo CSV pronto para planilha.
Exportar atributos para CSV🔗
Problema. O mapa tem os dados, mas alguém quer uma planilha.
Solução. Um script Groovy que percorre o ramo e grava CSV.
Antes de começar
- Ter lido scripting em Groovy
- Entender as permissões de script nas preferências
O que você vai aprender
- Extrair os atributos de um ramo para uma planilha
- Entender que permissões o script exige e por quê
- Escapar corretamente os campos do CSV
Requisitos🔗
Em Preferências → Scripts, habilite executar scripts sem assinatura e escrever arquivos.
Versão simples🔗
// AtributosParaCsv.groovy
def chaves = ['responsável', 'prazo', 'custo', 'status']
def sep = ';'
def linhas = [(['nó'] + chaves).join(sep)]
node.branch.each { n ->
if (n == node) return
def campos = [n.plainText] + chaves.collect { n[it]?.toString() ?: '' }
linhas << campos.collect { it.replace(sep, ',').replace('\n', ' ') }.join(sep)
}
def destino = new File(System.getProperty('user.home'), 'relatorio.csv')
destino.setText(linhas.join('\n'), 'UTF-8')
c.statusInfo = "${linhas.size() - 1} linhas em ${destino}"
Selecione o nó raiz do ramo e execute. O ponto e vírgula como separador é o que planilhas em português esperam por padrão.
Versão que descobre as chaves sozinha🔗
// AtributosParaCsvAuto.groovy
def sep = ';'
def nos = node.branch.findAll { it != node && it.attributes.names }
def chaves = nos.collectMany { it.attributes.names }.unique().sort()
if (!chaves) {
ui.informationMessage('Nenhum atributo encontrado neste ramo.')
return
}
def esc = { v -> (v ?: '').toString().replace(sep, ',').replace('\n', ' ') }
def linhas = [(['caminho'] + chaves).join(sep)]
nos.each { n ->
def caminho = []
def p = n
while (p && p != node.map.root) { caminho.add(0, p.plainText); p = p.parent }
linhas << ([esc(caminho.join(' > '))] + chaves.collect { esc(n[it]) }).join(sep)
}
def destino = new File(System.getProperty('user.home'), 'relatorio.csv')
destino.setText(linhas.join('\n'), 'UTF-8')
c.statusInfo = "${linhas.size() - 1} linhas, ${chaves.size()} colunas → ${destino}"
A coluna caminho preserva a hierarquia como Fase 1 > Infraestrutura > Servidores, o que salva a informação que a planilha plana perderia.
Respeitando o filtro🔗
Para exportar só o que o filtro ativo mostra, troque a coleta por:
def nos = node.branch.findAll { it != node && it.visible }
Assim você filtra o mapa, roda o script, e a planilha sai com exatamente o resultado da consulta.
Instalando no menu🔗
Grave o arquivo em:
~/.config/freeplane/1.11.x/scripts/AtributosParaCsv.groovy
Reinicie. Ele aparece em Ferramentas → Scripts. Atribua um atalho em Preferências → Atalhos.
Sem o Freeplane🔗
Se o objetivo é só extrair, um script Python sobre o XML dispensa abrir o programa:
import csv, xml.etree.ElementTree as ET
raiz = ET.parse('mapa.mm').getroot()
linhas = []
for no in raiz.iter('node'):
attrs = {a.get('NAME'): a.get('VALUE') for a in no.findall('attribute')}
if attrs:
linhas.append({'no': no.get('TEXT', ''), **attrs})
chaves = sorted({k for l in linhas for k in l})
with open('relatorio.csv', 'w', newline='', encoding='utf-8') as f:
w = csv.DictWriter(f, fieldnames=chaves, delimiter=';')
w.writeheader()
w.writerows(linhas)
Isso roda em pipeline, em CI, e sobre mapas que você nem abriu.
Erros comuns
- Habilitar escrita de arquivos e esquecer de reavaliar essa permissão depois
- Gerar CSV sem escapar aspas e separadores, e quebrar a planilha na primeira célula com vírgula
- Usar
,como separador num locale que espera;— a planilha abre tudo numa coluna - Exportar o ramo inteiro quando você queria só as folhas
Você aprendeu
- O script percorre
node.branche grava um arquivo — daí a permissão de escrita - Escapar campos é obrigatório, não opcional
- O separador depende do locale de quem vai abrir
- Rodar num mapa de cópia é a precaução mínima ao automatizar
Perguntas para reflexão
- Que duas permissões esta receita exige, e o que cada uma libera?
- Por que escapar campos importa mesmo em dados que parecem simples?
- Como você limitaria a exportação apenas às folhas do ramo?
- Que precaução se toma antes de rodar um script sobre um mapa de trabalho?