useExport
Panoramica
useExport gestisce la selezione campi, formato, filtri, ordinamento, applicazione di template salvati e l'esecuzione dell'export. Distingue tra export sincrono (Blob restituito direttamente) e asincrono (server risponde con 202 Accepted e exportId, segue polling). In entrambi i casi il file viene scaricato automaticamente con downloadBlob.
Internamente usa useExportTemplates per la gestione dei modelli e usePolling per il tracking degli export asincroni.
Inizializzazione
import { useExport } from '@pzeta/vue-importexport'
const {
loading, errore,
risorsa, campiDisponibili, campiSelezionati,
formato, nomeFile, etichettaRisorsa,
filtri, ordinamento, filtriPredefiniti, ordinamentoPredefinito,
exportResult, exportProgresso, isPolling,
templateManager,
loadMetadata, applyTemplate,
toggleField, selectAllFields, deselectAllFields, moveField,
executeExport, cancelExport, reset,
} = useExport()
Parametri
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
apiOverride | IExportClient & ITemplateClient | useApi() | Client da usare; senza, quello fornito con provide(IMPORT_EXPORT_API_KEY) |
Stato reattivo
| Proprietà | Tipo | Descrizione |
|---|---|---|
loading | Ref<boolean> | Operazione in corso |
errore | Ref<string | null> | Messaggio errore |
risorsa | Ref<string> | Codice risorsa |
campiDisponibili | Ref<CampoMetadato[]> | Campi esportabili (caricati da loadMetadata) |
campiSelezionati | Ref<string[]> | Nomi campo nell'ordine scelto dall'utente |
formato | Ref<FileFormato> | xlsx (default) o csv: gli unici che node-excel-export produce |
nomeFile | Ref<string> | Nome file forzato; vuoto (default) = nome calcolato, vedi Nome del file |
etichettaRisorsa | Ref<string> | Nome della risorsa per l'utente: se c'è, dà il nome al file (dalla 0.6.0) |
filtri | Ref<Record<string, unknown>> | Filtri del modello applicato |
ordinamento | Ref<OrdinamentoExport[]> | Ordinamento del modello applicato |
filtriPredefiniti | Ref<Record<string, unknown>> | Filtri di chi apre l'export (es. la pagina filtrata): valgono se il modello non ha filtri (dalla 0.6.0) |
ordinamentoPredefinito | Ref<OrdinamentoExport[]> | Ordinamento di chi apre l'export: vale se il modello non ha ordinamento (dalla 0.6.0) |
exportResult | Ref<ExportResult | null> | Risultato finale (sync o async) |
exportProgresso | Ref<ExportProgresso | null> | Progresso polling per async |
isPolling | Ref<boolean> | Polling attivo |
templateManager | oggetto | Restituito da useExportTemplates |
Metodi
loadMetadata(codiceRisorsa)
Imposta risorsa.value, carica campiDisponibili da getExportFieldMetadata e i template della risorsa via templateManager.loadTemplates.
await loadMetadata('anagrafica')
// campiDisponibili.value popolato
// templateManager.templates.value popolato
applyTemplate()
Applica il template attualmente selezionato (templateManager.selectedTemplate): popola campiSelezionati, formato, filtri, ordinamento.
- Un modello senza filtri o senza ordinamento li azzera: non eredita quelli del modello applicato prima, e tornano a valere i predefiniti.
- Un modello salvato fino alla 0.5.5 con formato
json, che il servizio non produce, lascia il formato corrente.
toggleField(campo), selectAllFields(), deselectAllFields(), moveField(from, to)
Manipolano campiSelezionati. moveField riordina spostando un elemento da from a to (drag-and-drop dal PickList).
executeExport()
Esegue la chiamata POST /export/execute. Comportamento:
- Costruisce
ExportRequestda stato corrente: campi, filtri e ordinamento effettivi (quelli del modello, o i predefiniti se il modello non li ha),modelloId, nome del file senza estensione - Se la risposta è un
Blob→ download immediato +exportResultsettato a{ tipo: 'sincrono', stato: 'completato' } - Se la risposta è asincrona (
202):stato: 'in_corso'→ parte pollingurlDownloadpresente → download immediatostato: 'errore'→ errore propagato
cancelExport()
Annulla l'export tramite AbortController. Ferma anche l'eventuale polling in corso.
reset()
Azzera lo stato dell'export: campi, formato, nomeFile, filtri e ordinamento del modello, risultato, polling, errori, template selezionato. etichettaRisorsa, filtriPredefiniti e ordinamentoPredefinito restano: li imposta chi apre l'export.
Nome del file
Se nomeFile è vuoto il nome si calcola alla data di oggi:
| Condizione | Nome | Dalla |
|---|---|---|
etichettaRisorsa valorizzata | <etichetta> <AAAA-MM-GG>.<formato> («Storico consegne 2026-10-15.xlsx») | 0.6.0 |
| altrimenti | <risorsa>_<AAAA-MM-GG>.<formato> («anagrafica_2026-10-15.xlsx») | 0.2.8 |
Al servizio va come nomeFile lo stesso nome senza estensione. Il nome indicato dal servizio per un export asincrono (nomeFile del risultato) ha la precedenza.
Tipo ExportRequest
interface ExportRequest {
risorsa: string
formato: FileFormato
campi: string[]
/** Passati intatti a node-excel-export: vedi «Filtri e ordinamento» in ExportDialog */
filtri?: Record<string, unknown>
/** Criteri in ordine di priorità, al massimo 10 */
ordinamento?: OrdinamentoExport[]
/** Nome del file senza estensione: il servizio aggiunge quella del formato */
nomeFile?: string
modelloId?: string
}
interface OrdinamentoExport {
campo: string
direzione: 'asc' | 'desc'
/** Posizione dei NULL (dalla 0.7.0, node-excel-export ≥ 1.1.15); senza, il default di PostgreSQL */
nulls?: 'first' | 'last'
}
Formati di filtri e ordinamento, e versioni del servizio che li supportano: ExportDialog › Filtri e ordinamento della pagina.
Tipo ExportResult
Discriminated union su tipo:
type ExportResult =
| {
tipo: 'sincrono'
stato: 'completato'
nomeFile: string
}
| {
tipo: 'asincrono'
exportId: string
stato: 'completato' | 'in_corso' | 'errore'
nomeFile?: string
dimensione?: number
righeEsportate?: number
urlDownload?: string
tempoEsecuzione?: number
}
Per distinguere i due casi basta il discriminante, che TypeScript restringe da solo:
if (result.tipo === 'asincrono') {
console.log('Export asincrono:', result.exportId)
}
isAsyncExportResult, definita accanto ai tipi, non è esportata a runtime: src/index.ts riesporta i tipi con export type *, che porta i tipi ma non le funzioni. Importarla dal pacchetto dà errore di compilazione.Esempio
const exporter = useExport()
await exporter.loadMetadata('anagrafica')
exporter.selectAllFields()
exporter.formato.value = 'xlsx'
exporter.etichettaRisorsa.value = 'Anagrafiche' // file: «Anagrafiche 2026-10-15.xlsx»
exporter.filtriPredefiniti.value = { attivo: true }
exporter.ordinamentoPredefinito.value = [
{ campo: 'cognome', direzione: 'asc' },
{ campo: 'datanascita', direzione: 'desc', nulls: 'last' },
]
await exporter.executeExport()
// Sincrono: file scaricato, exportResult.value.stato = 'completato'
// Async: polling parte, exportProgresso.value si aggiorna