cordelia24224 downloadsFill formatted Excel templates with properties from your notes and their related notes, preview the result and export it as XLSX files.
Fill formatted Excel templates with data from your Obsidian notes, preview the result and export it as .xlsx files.
The user interface is currently in Spanish.

Privacy: the plugin works offline. It makes no network requests and only reads and writes files inside your vault.
Plugin de Obsidian que llena templates de Excel (.xlsx) con las properties (frontmatter) de tus notas, preservando el formato del template: colores, anchos, celdas combinadas, logos y fórmulas.
Sirve para:

Privacidad: funciona sin conexión. No hace peticiones de red y solo lee y escribe archivos dentro de tu vault.
Desde Obsidian: Settings → Community plugins → Browse, busca «Excel Template Export» e instálalo.
Manual: descarga main.js, manifest.json y styles.css de la última release y cópialos a <vault>/.obsidian/plugins/excel-template-export/.
En examples/ hay dos Excel de ejemplo (Proceso.xlsx, Consolidado.xlsx) y templates.json con dos templates ya configurados para ellos.
Todo se maneja desde Templates de Excel: el icono de hoja de cálculo en la barra lateral, o el comando Abrir templates de Excel.
Verás una tarjeta por template, con una miniatura del Excel, qué genera ("Un archivo por cada Proceso") y cuántas notas hay disponibles. Desde cada tarjeta puedes Exportar, Editar, duplicar o eliminar.
Nuevo template: subes un Excel desde tu computador (o eliges uno del vault) y le pones nombre. El Excel solo necesita títulos y formato; las celdas de datos pueden quedar vacías.
categories, tags, type o carpeta) y basta un clic. También eliges cómo llamarlas («Proceso»), un filtro por defecto (por ejemplo «status no es Closed») y el orden. Los filtros se arman con desplegables: campo, condición y un valor elegido de los que existen en tus notas. Si prefieres, puedes escribirlos como texto.process» y lo agregas con un clic. Puedes renombrarlas («Interviews») y crear subconjuntos, como «Contratados = Interviews cuya decision es Hire».Todo se guarda solo. Revisar lista las celdas que no encuentran datos.
Desde la tarjeta, el editor, el comando Exportar a Excel… o el menú contextual de una nota.
.xlsx se escriben solo al confirmar con Exportar.Los templates se guardan en los datos del plugin (.obsidian/plugins/excel-template-export/data.json), no en notas. Las definiciones YAML antiguas (bloques excel-export en notas) se pueden importar con un botón desde la galería o con el comando Importar definiciones desde notas.
El formato interno de un template es el mismo que el de las definiciones YAML anteriores. Lo que sigue es útil para casos avanzados, como el modo «texto» de los filtros o el campo «Avanzado» de una celda.
| Sintaxis | Qué hace |
|---|---|
{{proceso.role}} |
Escalar. Si la celda tiene solo el placeholder, se escribe el valor tipado (número, fecha, booleano) y se respeta el formato de número de la celda. Mezclado con texto (Rol: {{proceso.role}}) da texto. |
{{interviews.tech rating}} |
Los nombres de property pueden tener espacios. |
{{proceso["mi.prop"]}} |
Corchetes para nombres con puntos. |
{{interviews.interviewed.seniority}} |
Si un segmento es un link, se resuelve y se navega. Si es una lista de links, se mapea. |
{{proceso.file.name}} |
Pseudo-properties: file.name, file.path, file.folder, file.ext, file.ctime, file.mtime, file.link. |
{{@index}}, {{@count}}, {{@today}}, {{@now}}, {{@exportName}} |
Variables especiales (@index es 1-based dentro de un #each). |
{{#each interviews}}… |
Al inicio de una celda: marca la fila como plantilla y la repite una vez por elemento (copiando estilos, alto y merges horizontales). Un #each por fila; puede haber varias filas #each por hoja. |
Dentro de una fila #each interviews, {{interviews.decision}} es el elemento actual y los campos de la raíz siguen disponibles ({{proceso.role}}).
{{path | pipe:arg | pipe}}
| Pipe | Efecto |
|---|---|
raw |
Sin normalizar (mantiene [[...]]). |
target |
Nombre de la nota destino en vez del alias. |
join:"; " |
Separador de lista. |
first |
Primer elemento de una lista. |
count |
Tamaño de una lista o colección: {{hires | count}}. |
stars |
Cuenta ⭐ (½ suma 0.5) y devuelve un número. |
date:"dd/MM/yyyy" |
Formatea como texto (tokens yyyy yy MM M dd d HH H mm ss). Sin pipe, las fechas van como fecha de Excel. |
default:"-" |
Valor si está vacío. |
upper / lower |
Mayúsculas / minúsculas. |
link |
Hipervínculo a obsidian://open?... con el texto normalizado. |
| Modo | Resultado |
|---|---|
file-per-root |
Un .xlsx por nota raíz. |
sheet-per-root |
Un .xlsx; la primera hoja del template se clona por raíz (nombre de hoja sanitizado a 31 caracteres y sin repetir). Las demás hojas se mantienen y ven la colección de raíces ({{proceso | count}}, {{#each proceso}}). |
single |
Un .xlsx; la colección de raíces se llama como el alias: {{#each proceso}}. Flatten: {{#each proceso.interviews}} da una fila por interview, con acceso al padre ({{proceso.role}}) y al elemento ({{interviews.interviewed}}). Dentro de {{#each proceso}} también están las relaciones de cada raíz ({{interviews | count}}). |
expr := or ; or := and ("or" and)* ; and := unary ("and" unary)*
unary := "not" unary | "(" expr ")" | path op value | path ("exists" | "!exists")
op := == | != | > | >= | < | <= | contains | !contains
value := "texto" | 123 | true | false | null | today | date("2026-03-01") | alias
role == "Backend" matchea [[Backend]] y [[Roles/Backend|Back]].contains verifica pertenencia; == es verdadero si algún elemento coincide.contains es substring sin distinguir mayúsculas.YYYY-MM-DD, hora opcional); today es la fecha local.!=, !contains y !exists. campo == null es verdadero si falta.["tech rating"] >= 3. Los paths pueden navegar links: interviewed.seniority == "Junior".process == proceso.| Entrada | Salida (default) |
|---|---|
[[Backend]] |
Backend |
[[Celula X|Alias]] |
Alias (links: target → Celula X) |
[[Carpeta/Nota]] |
Nota |
| lista | elementos normalizados unidos con listSeparator |
2026-03-01 |
fecha de Excel (formato de la celda o yyyy-mm-dd) |
⭐⭐⭐ |
3 |
| número / booleano | tipo nativo |
| vacío / null | emptyValue |
| objeto | JSON compacto + warning |
Las fechas se interpretan en hora local, sin corrimiento por zona horaria.
excel-export antiguos en templates.Después de exportar aparece un aviso (3 archivos generados, 2 warnings) con Ver detalle (datos sin resolver, links rotos, fórmulas) y Abrir carpeta. Un dato que no se encuentra nunca cancela el export.
| Setting | Default |
|---|---|
| Carpeta de los Excel de template (los que subes) | Templates/Excel |
| Carpeta de salida por defecto | Exports/out/ |
| Links | display |
| Separador de listas | , |
| Estrellas | number |
| Valor vacío | "" |
| Fila repetida sin elementos | remove |
| Abrir archivo al terminar (desktop) | false |
| Sobrescritura por defecto | ask |
| Previsualizar antes de exportar | true |
Así se guarda un template en data.json. Es el mismo esquema que el de los bloques YAML antiguos:
name: Ficha de proceso
template: Templates/Excel/Proceso.xlsx
root:
alias: proceso # nombre interno (se deriva de label)
label: Proceso
where: categories contains "Talent Acquisition Process"
filter: status != "Closed"
sort: created desc
mode: file-per-root # file-per-root | sheet-per-root | single
relations:
interviews:
label: Interviews
from: categories contains "Interview Evaluations" # opcional
on: process -> proceso
sort: date asc
contratados:
label: Contratados
source: interviews
filter: decision == "Hire"
output:
folder: Exports/out
filename: '{{proceso.file.name}}.xlsx'
repeatSheet: Proceso # sheet-per-root: hoja que se copia
sheetName: '{{proceso.file.name}}'
overwrite: ask # ask | overwrite | suffix
cells:
Proceso!B2: proceso.team
Proceso!E4: proceso.contratados | count
Proceso!A7: interviews.interviewed
rows:
Proceso!7: interviews
Hoja!): las de abajo se desplazan y los rangos que contienen la fila plantilla se expanden (AVERAGE(G7:G7) → AVERAGE(G7:G9)). Si la fila #each queda sin elementos y se elimina, las referencias a esa fila quedan en #REF! (como en Excel) y se avisa en el reporte; usa emptyBlock: blank para conservarla. Referencias de filas completas (7:7), nombres estructurados y fórmulas matriciales no se ajustan.#each al final de la hoja.#each se descombinan (con warning).sheet-per-root no se copian a las hojas clonadas (warning).on solo admite <campo> -> <aliasRaíz>..base; los filtros usan su propio lenguaje.categories contains "TH" funciona en ambos casos.status != "Closed" (un status faltante cuenta como activo).½ suma 0.5 y los números pasan tal cual.isDesktopOnly: true hasta probarlo.npm install
npm test # Vitest, en Node, sin Obsidian
npm run build # typecheck + bundle (main.js)
npm run dev # watch
npm version patch # o minor / major: actualiza package.json, manifest.json y versions.json, y crea el tag
git push && git push --tags
Otra opción, sin tags locales: sube el cambio de versión a main y en GitHub ve a Actions → Release Obsidian plugin → Run workflow. El workflow toma la versión de manifest.json, crea el tag y publica la release.
Antes, escribe las notas en release-notes/<versión>.md (si no existen, se generan a partir de los commits). El workflow Release Obsidian plugin prueba, compila y publica la release con main.js, manifest.json y styles.css; Obsidian ofrecerá la actualización a los usuarios.
src/
main.ts, settings.ts # plugin, comandos, settings (Obsidian)
adapter/ # VaultAdapter: Obsidian + memoria (tests)
model/ # NoteRecord, reporte de warnings
config/ # schema, validación y parseo del YAML
query/ # lexer, parser, evaluador y sort de filtros
graph/ # paths, relaciones (índice inverso), runtime
values/ # links, normalización, pipes
excel/ # placeholders, scanner, motor, fórmulas, IO
export/ # runner (build en memoria + escritura) y validación
setup/ # descubrimiento de campos, tipos de nota, relaciones sugeridas, filtros visuales
store/ # templates guardados en el plugin (alta, renombres, estado)
ui/ # gestor (galería + editor en 4 pasos), exportar, vista previa, componentes
tests/ # tests del core + fixture del dominio (vault.json)
El core (query, graph, values, excel, export, config) no importa obsidian; Obsidian entra solo por adapter/obsidian-adapter.ts y ui/.