Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Semplici report in Excel

Esportare i risultati di query, viste o SP, in un formato compatibile con Excel
Esportare i risultati di query, viste o SP, in un formato compatibile con Excel
Link copiato negli appunti

In questo articolo esaminiamo una semplicissima tecnica, già proposta in Classic ASP da Roberto Caccianini, per generare report importabili da Excel con ASP.NET.

La tecnica di base consiste nel costruire il markup di un foglio excel inserendovi i dati prelevati da una query o da una Stored Procedure. Ciò che cercheremo di fare è rendere tutto più semplice creando una piccola classe che compia questo lavoro al posto nostro e riusandola a piacere.

Per poter visualizzare il file generato, se non abbiamo installato il foglio elettronico di Microsoft, avremo bisogno almeno del visualizzatore Excel.

Il file "HTML"

Ormai è noto che si può salvare un file Excel come "pagina HTML", sfruttando questa caratteristica possiamo evitare alcuni problemi di permessi e autorizzazioni che potremo incontrare usando, ad esempio, gli Iterop di Office (PIA) all'interno di una applicazione Web, specie se in Hosting.

Diamo uno sguardo alla struttura che dovrà avere il nostro file. Di seguito il namespace e l'XML che bisogna inserire all'inizio di un qualsiasi file di excel, con estensione ".xls".

Listato 1. Esempio di header del file Excel

<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">

<head>
  <meta http-equiv=Content-Type content="text/html; charset=windows-1252">
  <meta name=ProgId content=Excel.Sheet><meta name=Generator content="Microsoft Excel 9">
  <!--[if gte mso 9]>
  <xml>
  <!-- Descrizione di tutto il file -->
  <x:ExcelWorkbook>
    <!-- Fogli di lavoro -->
    <x:ExcelWorksheets>
      <!-- Definizione del foglio -->
      <x:ExcelWorksheet>
        <!-- Nome del foglio -->
        <x:Name>mioFoglio</x:Name>
        <!-- opzioni -->
        <x:WorksheetOptions>
          <x:Selected/>
          <x:ProtectContents>False</x:ProtectContents>
          <x:ProtectObjects>False</x:ProtectObjects>
          <x:ProtectScenarios>False</x:ProtectScenarios>
        </x:WorksheetOptions>
      </x:ExcelWorksheet>
    </x:ExcelWorksheets>
    <!-- Protezione a livello di file -->
    <x:ProtectStructure>False</x:ProtectStructure>
    <x:ProtectWindows>False</x:ProtectWindows>
  </x:ExcelWorkbook>
  </xml>
  <![endif]-->
</head>

A questo header possiamo associare dei particolari fogli di stile CSS, con regole e caratteristiche molto simili a quelle utilizzate per HTML/XHTML, utilizzando il tag <style>.

Il contenuto della tabella sarà inserito nella sezione <body> del file come una comunissima <table> in HTML.

La classe

Lo schema UML (By Visual Studio) evidenzia la struttura della classe che farà da motore per i nostri file.

Le proprietà

  • Connessione
  • DaFormattare
  • DestPath Server.MapPath()
  • Query
  • Stile
  • HeaderPath

Come immaginiamo, dovremo anzitutto impaginare i dati come faremmo per una classica tabella HTML. Quindi tramite l'ausilio di un file .css possiamo andare modificarne la formattazione.

I metodi

Vediamo come implementare la logica di lettura dei dati. Abbiamo bisogno di creare una DataTable e sfruttarne le funzionalità per poi poterle riflettere nel file di excel. Pensiamo ad esempio di voler controllare l'allineamento dei dati a seconda del tipo di dato (Numero, Stringa) oppure di voler modificare l'intestazione con i nomi delle colonne.

Spendiamo allora qualche metodo per semplificare la connessione al DataBase. Alcuni metodi sono stati implementati per lavorare con SQL Server, ma possiamo immaginare di virtualizzare la classe ed implementarla per i diversi connettori.

Abbiamo immaginato:

  • il metodo CostruisciConnessione() SQLConnection
  • il metodo CostruisciDati() DataTable
  • CostruisciFile()

    Riconosce i DataType e i DataValue di ogni colonna e ne fornisce la opportuna visualizzazione.

I primi due metodi sono molto semplici, servono per creare un SQLCommand che legge la query da noi impostata, dichiarare un DataAdapter che riempie le tabelle di un DataSet. La tabella "numero 0" di questo DataSet (mioDataSet.Tables[0]) è quella che contiene il risultato della query e sarà esaminata dal metodo CostruisciFile() che usiamo per generare tutto il markup.

Tutto si gioca nel metodo CostruisciFile(). Ne abbiamo implementata una versione molto semplice che si limita a:

  • caricare un header esterno
  • applicare o meno un semplice foglio di stile
  • leggere i dati dalla DataTable

Esaminiamo solo alcuni spezzoni di codice che possono essere di maggior rilevanza. Ad esempio la generazione automatica delle intestazioni per le colonne, e l'inserimento dei dati che tenga conto dei tipi di dato che vengono dal database.

Listato 2. Stralcio di CostruisciFile(): la costruzione della tabella

...

// inserisce i tag iniziali
fileDestinazione.Append("<body><table>");

// finalmente inserisce i dati
DataTable tabella = CostruisciDati();

// comincia dai nomi delle colonne
fileDestinazione.Append("<tr>");

Hashtable Colonne = new Hashtable();

// per ogni colonna scrive il nome nel file
foreach(DataColumn colonna in tabella.Columns)
{
  fileDestinazione.Append("<th>"+colonna.ColumnName+"</th>");

  // registra il nome ed il tipo in una hashtable
  Colonne.Add(colonna.ColumnName,colonna.DataType);
}
fileDestinazione.Append("</tr>");

// poi inserisce i valori nelle righe
foreach(DataRow riga in tabella.Rows)
{
  fileDestinazione.Append("<tr>");

  // .. utilizzando la hashtable delle colonne
  // per stabilire il tipo e la relativa formattazione
  foreach(string NomeColonna in Colonne.Keys)
    fileDestinazione.Append("<td class=""+Colonne[NomeColonna].ToString()+"

  fileDestinazione.Append("</tr>");
}

// inserisce i tag finali
fileDestinazione.Append("</table></body></html>");

...

Una volta generato il file possiamo salvarlo con il metodo SalvaFile(), richiamarlo con un link e lasciare che l'utente lo scarichi.

Considerazioni finali

Un metodo molto semplice, se volgiamo anche sbrigativo e non attualissimo, ma con molti punti a suo favore.

Una prima considerazione interessante è che lo stesso modello di lavoro possiamo applicarlo banalmente al più attuale markup OpenDocument (anche se questo "vecchio" formato rimane compatibile con moltissime versioni di Excel).

È chiaro che risulta più macchinoso rispetto all'utilizzo dei PIA, che però necessitano di installazione (pensiamo ad applicazioni in Hosting) e di un esborso per la licenza.

Inoltre può darci l'ispirazione per implementare una soluzione simile su piattaforme diverse come PHP, o Ruby.

Ti consigliamo anche