In questo articolo vengono descritti in modo dettagliato
diversi metodi per il trasferimento di dati in Microsoft Excel 2002 da un
programma Microsoft Visual C# 2005 o Microsoft Visual C# .NET. Vengono inoltre
presentati i vantaggi e gli svantaggi di ogni metodo in modo da poter adottare
la soluzione più appropriata alla situazione.
La tecnica utilizzata con maggiore frequenza per trasferire dati
a una cartella di lavoro di Excel è l'automazione. Mediante l'automazione, è possibile chiamare metodi e proprietà
specifiche di Excel. L'automazione fornisce una notevole flessibilità per
specificare la posizione dei dati nella cartella di lavoro, per formattare la
cartella di lavoro e per definire varie impostazioni in fase di
esecuzione.
Con l'automazione, è possibile utilizzare diverse
tecniche per trasferire i dati:
Trasferire i dati cella per cella.
Trasferire i dati di una matrice in un intervallo di
celle.
Trasferire i dati di un recordset ADO in un intervallo di
celle mediante il metodo CopyFromRecordset.
Creare un oggetto QueryTable su un foglio di lavoro di Excel che contiene i risultati di una
query a un'origine dati ODBC o OLEDB.
Trasferire i dati negli Appunti, quindi incollare il
contenuto degli Appunti in un foglio di Excel.
Per il trasferimento di dati in Excel, è possibile utilizzare
diversi metodi che non richiedono necessariamente l'automazione. Se si esegue
un programma lato server, questo può essere un metodo valido per non sottoporre
i client all'elaborazione di grandi quantità di dati.
Per trasferire
i dati senza automazione, è possibile utilizzare i seguenti metodi:
Trasferire i dati in un file di testo delimitato da
tabulazioni o da virgole che possa essere analizzato nelle celle di un foglio
di lavoro di Excel.
Trasferire i dati in un foglio di lavoro mediante
ADO.NET.
Trasferire i dati XML in Excel (versioni 2002 e 2003) per
fornire dati formattati e disposti in righe e colonne.
In questo articolo vengono forniti una spiegazione e un esempio
di codice per ognuna di queste tecniche. Nella sezione
Creare il progetto completo di esempio di
Visual C# 2005 o Visual C# .NET, più avanti in questo articolo,
viene illustrato come creare un programma Visual C# .NET che esegua ogni
tecnica.
Utilizzare l'automazione per trasferire dati cella per cella
Con l'automazione è possibile trasferire dati in un foglio di
lavoro una cella alla volta:
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Add data to cells in the first worksheet in the new workbook.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange.Value = "Last Name";
m_objRange = m_objSheet.get_Range("B1", m_objOpt);
m_objRange.Value = "First Name";
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.Value = "Doe";
m_objRange = m_objSheet.get_Range("B2", m_objOpt);
m_objRange.Value = "John";
// Apply bold to cells A1:B1.
m_objRange = m_objSheet.get_Range("A1", "B1");
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
Il trasferimento di dati cella per cella è accettabile per quantità
ridotte di dati. Questo metodo offre la flessibilità di immettere i dati in
qualsiasi punto della cartella di lavoro e di formattare le celle in base alle
condizioni in fase di esecuzione. Non è tuttavia opportuno utilizzare questo
metodo se è necessario trasferire una grande quantità di dati in una cartella
di Excel. Ogni oggetto Range acquisito in fase di esecuzione causa una richiesta di
interfaccia che rallenta il trasferimento dei dati. Inoltre, in Microsoft
Windows 95, Microsoft Windows 98 e Microsoft Windows Millennium Edition (Me) è
presente un limite di 64 KB per le richieste di interfaccia. Se le richieste di
interfaccia superano i 64 KB, è possibile che il server di automazione (Excel)
si blocchi o che vengano visualizzati messaggi di errore che indicano
l'insufficienza di memoria.
Per ulteriori informazioni, fare clic sul numero
dell'articolo della Microsoft Knowledge Base riportato di seguito:
216400
(http://support.microsoft.com/kb/216400/
)
PRB: Blocco dell'applicazione client con Windows 95/98 a causa dell'automazione COM tra processi
Come indicato, il trasferimento di dati cella per
cella è accettabile solo per quantità ridotte di dati. Se è necessario
trasferire in Excel grandi quantità di dati, utilizzare uno degli altri metodi
illustrati in questo articolo per il trasferimento di dati in
massa.
Per ulteriori
informazioni e per un esempio di automazione di Excel mediante Visual C# .NET,
fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di
seguito:
302084
(http://support.microsoft.com/kb/302084/
)
HOWTO: Automatizzare Microsoft Excel da Visual C# .NET
Utilizzare l'automazione per trasferire matrici di dati in un intervallo di un foglio di lavoro
È possibile trasferire una matrice di dati in un intervallo di
celle con un'unica operazione:
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
// Create an array for the headers and add it to cells A1:C1.
object[] objHeaders = {"Order ID", "Amount", "Tax"};
m_objRange = m_objSheet.get_Range("A1", "C1");
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Create an array with 3 columns and 100 rows and add it to
// the worksheet starting at cell A2.
object[,] objData = new Object[100,3];
Random rdm = new Random((int)DateTime.Now.Ticks);
double nOrderAmt, nTax;
for(int r=0;r<100;r++)
{
objData[r,0] = "ORD" + r.ToString("0000");
nOrderAmt = rdm.Next(1000);
objData[r,1] = nOrderAmt.ToString("c");
nTax = nOrderAmt*0.07;
objData[r,2] = nTax.ToString("c");
}
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange = m_objRange.get_Resize(100,3);
m_objRange.Value = objData;
// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
Se si trasferiscono i dati mediante una matrice anziché cella per
cella, è possibile migliorare notevolmente le prestazioni quando occorre
trasferire grandi quantità di dati. Considerare le seguenti righe del codice
precedentemente indicato per il trasferimento di dati in 300 celle del foglio
di lavoro:
Questo codice rappresenta due richieste di interfaccia: una per
l'oggetto Range restituito dal metodo Range e l'altra per l'oggetto Range restituito dal metodo Resize. Viceversa, per il trasferimento dei dati cella per cella sono
necessarie richieste per 300 interfacce per gli oggetti Range. Quando è possibile, è opportuno sfruttare il trasferimento dei
dati in massa e ridurre il numero di richieste di interfaccia effettuate.
Per ulteriori informazioni sull'utilizzo di matrici per
ottenere e impostare valori in intervalli con l'automazione di Excel, fare clic
sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito:
302096
(http://support.microsoft.com/kb/302096/
)
How to Automatizzare Excel da Visual C# .Net per inserire o ottenere
dati in un intervallo mediante matrici
Utilizzare l'automazione per trasferire un recordset ADO in un intervallo di un foglio di lavoro
I modelli di oggetto per Excel 2000, Excel 2002 ed Excel 2003
forniscono il metodo CopyFromRecordset per il trasferimento di un recordset ADO in un intervallo su un
foglio di lavoro. Nel codice riportato di seguito viene illustrato come
automatizzare Excel per il trasferimento del contenuto della tabella Orders nel
database di esempio Northwind mediante il metodo CopyFromRecordset:
// Create a Recordset from all the records in the Orders table.
ADODB.Connection objConn = new ADODB.Connection();
ADODB._Recordset objRS = null;
objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", "", "", 0);
objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
object objRecAff;
objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff,
(int)ADODB.CommandTypeEnum.adCmdTable);
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
// Get the Fields collection from the recordset and determine
// the number of fields (or columns).
System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
int nFields = objRS.Fields.Count;
// Create an array for the headers and add it to the
// worksheet starting at cell A1.
object[] objHeaders = new object[nFields];
ADODB.Field objField = null;
for(int n=0;n<nFields;n++)
{
objFields.MoveNext();
objField = (ADODB.Field)objFields.Current;
objHeaders[n] = objField.Name;
}
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange = m_objRange.get_Resize(1, nFields);
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Transfer the recordset to the worksheet starting at cell A2.
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);
// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
// Close the recordset and connection.
objRS.Close();
objConn.Close();
Nota CopyFromRecordset funziona solo con oggetti Recordset ADO. Non è possibile utilizzare DataSet creato mediante ADO.NET con il metodo CopyFromRecordset. Nelle sezioni che seguono sono riportati diversi esempi in cui
viene illustrato come trasferire dati in Excel mediante ADO.NET.
Utilizzare l'automazione per creare un oggetto QueryTable su un foglio di lavoro
Un oggetto QueryTable rappresenta una tabella creata dai dati restituiti da un'origine
dati esterna. Quando si automatizza Excel, è possibile creare una QueryTable fornendo una stringa di connessione a un'origine dati OLE DB o
ODBC e una stringa SQL. Il recordset viene generato in Excel e inserito nel
foglio di lavoro nella posizione specificata. Gli oggetti QueryTable offrono i seguenti vantaggi rispetto al metodo CopyFromRecordset:
La creazione del recordset e il relativo inserimento nel
foglio di lavoro sono gestiti da Excel.
È possibile salvare la query con l'oggetto QueryTable e aggiornarla successivamente per ottenere un recordset
aggiornato.
Quando si aggiunge una nuova QueryTable al foglio di lavoro, è possibile specificare che i dati già
esistenti nelle celle del foglio di lavoro vengano spostati per gestire i nuovi
dati. Per ulteriori informazioni, vedere la proprietà RefreshStyle.
Nel codice riportato di seguito viene illustrato come
automatizzare Excel 2000, Excel 2002 o Excel 2003 per creare una nuova QueryTable in un foglio di lavoro di Excel utilizzando i dati del database
di esempio Northwind:
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Create a QueryTable that starts at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objQryTables = m_objSheet.QueryTables;
m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
"OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", m_objRange, "Select * From Orders");
m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
m_objQryTable.Refresh(false);
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
Utilizzare gli Appunti di Windows
È possibile utilizzare gli Appunti di Windows per trasferire dati
in un foglio di lavoro. Per incollare i dati in più celle di un foglio di
lavoro, è possibile copiare una stringa in cui le colonne sono delimitate da
tabulazioni e le righe da ritorni a capo. Nel codice riportato di seguito viene
illustrato l'utilizzo degli Appunti di Windows in Visual C# .NET per trasferire
dati in Excel:
// Copy a string to the Windows clipboard.
string sData = "FirstName\tLastName\tBirthdate\r\n" +
"Bill\tBrown\t2/5/85\r\n" +
"Joe\tThomas\t1/1/91";
System.Windows.Forms.Clipboard.SetDataObject(sData);
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Paste the data starting at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objSheet.Paste(m_objRange, false);
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
Creare un file di testo delimitato analizzabile in Excel in righe e colonne
In Excel è possibile aprire file delimitati da tabulazioni o da
virgole e analizzare correttamente i dati nelle celle. Questa funzione può
essere utilizzata per trasferire grandi quantità di dati in un foglio di lavoro
servendosi dell'automazione in modo limitato. Questo metodo può essere valido
per un programma client-server perché il file di testo può essere generato lato
client. È quindi possibile aprire il file di testo dal client, utilizzando
l'automazione quando necessario.
Nel codice riportato di seguito
viene illustrato come generare un file di testo delimitato da tabulazioni da
dati letti con ADO.NET:
// Connect to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
objConn.Open();
// Execute a command to retrieve all records from the Employees table.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand(
"Select * From Employees", objConn);
System.Data.OleDb.OleDbDataReader objReader;
objReader = objCmd.ExecuteReader();
// Create the FileStream and StreamWriter object to write
// the recordset contents to file.
System.IO.FileStream fs = new System.IO.FileStream(
m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
System.IO.StreamWriter sw = new System.IO.StreamWriter(
fs, System.Text.Encoding.Unicode);
// Write the field names (headers) as the first line in the text file.
sw.WriteLine(objReader.GetName(0) + "\t" + objReader.GetName(1) +
"\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
"\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));
// Write the first six columns in the recordset to a text file as
// tab-delimited.
while(objReader.Read())
{
for(int i=0;i<=5;i++)
{
if(!objReader.IsDBNull(i))
{
string s;
s = objReader.GetDataTypeName(i);
if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
{
sw.Write(objReader.GetInt32(i).ToString());
}
else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
{
sw.Write(objReader.GetDateTime(i).ToString("d"));
}
else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
{
sw.Write(objReader.GetString(i));
}
}
if(i<5) sw.Write("\t");
}
sw.WriteLine();
}
sw.Flush(); // Write the buffered data to the filestream.
// Close the FileStream.
fs.Close();
// Close the reader and the connection.
objReader.Close();
objConn.Close();
Il codice precedentemente riportato non utilizza automazione. Tuttavia,
se lo si desidera, è possibile utilizzare l'automazione per aprire il file di
testo e salvarlo nel formato di cartella di lavoro di Excel, in modo analogo al
seguente:
// Open the text file in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1,
Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
false, true, false, false, false, false, m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt);
m_objBook = m_objExcel.ActiveWorkbook;
// Save the text file in the typical workbook format and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
Trasferire dati in un foglio di lavoro mediante ADO.NET
È possibile utilizzare il provider Microsoft Jet OLE DB per
aggiungere record a una tabella in una cartella di lavoro di Excel esistente.
Una tabella in Excel è semplicemente un intervallo di celle che può
presentare un nome definito. In genere, la prima riga dell'intervallo contiene
le intestazioni (o nomi di campo) e tutte le altre righe dell'intervallo
contengono i record.
Tramite il seguente codice vengono aggiunti due
record a una tabella in Book7.xls. La tabella in questo caso è Sheet1:
// Establish a connection to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
"Book7.xls;Extended Properties=Excel 8.0;");
objConn.Open();
// Add two records to the table named 'MyTable'.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Bill', 'Brown')";
objCmd.ExecuteNonQuery();
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Joe', 'Thomas')";
objCmd.ExecuteNonQuery();
// Close the connection.
objConn.Close();
Quando si aggiungono record mediante ADO.NET come illustrato in questo
esempio, la formattazione della cartella di lavoro viene mantenuta. Ogni record
aggiunto a una riga acquisisce il formato della riga precedente.
Per ulteriori informazioni sull'utilizzo di
ADO.NET, fare clic sui numeri degli articoli della Microsoft Knowledge Base
riportati di seguito:
306636
(http://support.microsoft.com/kb/306636/
)
HOW TO: Connettersi a un database ed eseguire un comando utilizzando ADO.NET e Visual C# .NET
314145
(http://support.microsoft.com/kb/314145/
)
HOW TO: Compilare un oggetto DataSet da un database con Visual C# .NET
307587
(http://support.microsoft.com/kb/307587/
)
HOW TO: Aggiornare un database da un oggetto DataSet utilizzando Visual C# .NET
Per ulteriori
informazioni sull'utilizzo del provider Jet OLEDB con origini dati Excel, fare
clic sui numeri degli articoli della Knowledge Base riportati di seguito:
316934
(http://support.microsoft.com/kb/316934/
)
HOW TO: Utilizzare ADO.NET per recuperare e modificare record in una cartella di lavoro di Excel con Visual Basic .NET
278973
(http://support.microsoft.com/kb/278973/
)
SAMPLE: Utilizzo di ADO per leggere e scrivere dati in cartelle di lavoro di Excel illustrato in ExcelADO
257819
(http://support.microsoft.com/kb/257819/
)
How to Utilizzare ADO con dati di Excel da Visual Basic o VBA
Trasferire dati XML (Excel 2002 ed Excel 2003)
In Excel 2002 e 2003 è possibile aprire qualsiasi file XML che
presenti una forma corretta. È possibile aprire direttamente file XML
utilizzando il comando Apri del menu File oppure tramite programmazione utilizzando i metodi Open o OpenXML dell'insieme Workbooks. Se si creano file XML da utilizzare in Excel, è anche possibile
creare fogli di stile per formattare i dati.
Per ulteriori informazioni sull'utilizzo di XML con Excel
2002, fare clic sui numeri degli articoli della Microsoft Knowledge Base
riportati di seguito:
307029
(http://support.microsoft.com/kb/307029/
)
HOW TO: Trasferire dati XML a Microsoft Excel 2002 utilizzando Visual C# .NET
288215
(http://support.microsoft.com/kb/288215/
)
INFO: Microsoft Excel 2002 e XML
Creazione del progetto di esempio completo di Visual C# .NET
Creare una nuova cartella denominata C:\ExcelData. Le
cartelle di lavoro di Excel vengono memorizzate in questa cartella dal
programma di esempio.
Creare una nuova cartella di lavoro in cui scrivere
l'esempio:
Aprire una nuova cartella di lavoro in
Excel.
Sul Foglio1 della nuova cartella di lavoro digitare
FirstName nella cella A1 e
LastName nella cella B1.
Selezionare l'intervallo di celle A1:B1.
Scegliere Nome dal menu Inserisci, quindi fare clic su Definisci. Digitare il nome MyTable e scegliere OK.
Salvare la cartella di lavoro come
C:\Exceldata\Book7.xls.
Chiudere Excel.
Avviare Microsoft Visual Studio 2005 o Microsoft Visual
Studio .NET. Scegliere Nuovo dal menu File, quindi fare clic su Progetto. In Progetti di Visual C# o Visual C# selezionare Applicazione Windows. Per impostazione predefinita, verrà creato Form1.
Aggiungere un riferimento alla libreria di oggetti di Excel
e all'assembly di interoperabilità primario ADODB. Per effettuare questa
operazione, attenersi alla seguente procedura:
Scegliere Aggiungi riferimento dal menu Progetto.
Nella scheda NET individuare ADODB, quindi scegliere Seleziona.
Nota In Visual Studio 2005 non è necessario fare clic su
Seleziona.
Nella scheda COM individuare la libreria di oggetti di Microsoft Excel 10.0 e la libreria di oggetti di Microsoft Excel 11.0, quindi fare clic su Seleziona.
Nota In Visual Studio 2005 non è necessario fare clic su
Seleziona.
Nota Se si utilizza Microsoft Excel 2002 e non è ancora stata eseguita
questa operazione, si consiglia di scaricare e installare gli assembly di
interoperabilità primari (PIA) di Microsoft Office XP.
Per ulteriori informazioni sugli assembly di interoperabilità primari di Office
XP, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato
di seguito:
328912
(http://support.microsoft.com/kb/328912/
)
Assembly di interoperabilità primari (PIA) di Microsoft Office XP disponibili per il download
Nella finestra di dialogo Aggiungi riferimento scegliere OK per accettare le selezioni.
Aggiungere un controllo Casella combinata e un controllo Pulsante a Form1.
Aggiungere gestori di eventi per l'evento Load di Form e per gli eventi Click del controllo Pulsante:
In visualizzazione Progettazione per Form1.cs, fare
doppio clic su Form1.
Viene creato il gestore per l'evento Load di Form e viene visualizzato in Form1.cs.
Scegliere Finestra di progettazione dal menu Visualizza per tornare alla visualizzazione Progettazione.
Fare doppio clic su Button1.
Viene creato il gestore per l'evento Click del pulsante e viene visualizzato in Form1.cs.
// Excel object references.
private Excel.Application m_objExcel = null;
private Excel.Workbooks m_objBooks = null;
private Excel._Workbook m_objBook = null;
private Excel.Sheets m_objSheets = null;
private Excel._Worksheet m_objSheet = null;
private Excel.Range m_objRange = null;
private Excel.Font m_objFont = null;
private Excel.QueryTables m_objQryTables = null;
private Excel._QueryTable m_objQryTable = null;
// Frequenty-used variable for optional arguments.
private object m_objOpt = System.Reflection.Missing.Value;
// Paths used by the sample code for accessing and storing data.
private object m_strSampleFolder = "C:\\ExcelData\\";
private string m_strNorthwind = "C:\\Program Files\\Microsoft Office\\Office10\\Samples\\Northwind.mdb";
private void Form1_Load(object sender, System.EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.Items.AddRange(new object[]{
"Use Automation to Transfer Data Cell by Cell ",
"Use Automation to Transfer an Array of Data to a Range on a Worksheet ",
"Use Automation to Transfer an ADO Recordset to a Worksheet Range ",
"Use Automation to Create a QueryTable on a Worksheet",
"Use the Clipboard",
"Create a Delimited Text File that Excel Can Parse into Rows and Columns",
"Transfer Data to a Worksheet Using ADO.NET "});
comboBox1.SelectedIndex = 0;
button1.Text = "Go!";
}
private void button1_Click(object sender, System.EventArgs e)
{
switch (comboBox1.SelectedIndex)
{
case 0 : Automation_CellByCell(); break;
case 1 : Automation_UseArray(); break;
case 2 : Automation_ADORecordset(); break;
case 3 : Automation_QueryTable(); break;
case 4 : Use_Clipboard(); break;
case 5 : Create_TextFile(); break;
case 6 : Use_ADONET(); break;
}
//Clean-up
m_objFont = null;
m_objRange = null;
m_objSheet = null;
m_objSheets = null;
m_objBooks = null;
m_objBook = null;
m_objExcel = null;
GC.Collect();
}
private void Automation_CellByCell()
{
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Add data to cells of the first worksheet in the new workbook.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange.set_Value(m_objOpt,"Last Name");
m_objRange = m_objSheet.get_Range("B1", m_objOpt);
m_objRange.set_Value(m_objOpt,"First Name");
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.set_Value(m_objOpt,"Doe");
m_objRange = m_objSheet.get_Range("B2", m_objOpt);
m_objRange.set_Value(m_objOpt,"John");
// Apply bold to cells A1:B1.
m_objRange = m_objSheet.get_Range("A1", "B1");
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
}
private void Automation_UseArray()
{
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
// Create an array for the headers and add it to cells A1:C1.
object[] objHeaders = {"Order ID", "Amount", "Tax"};
m_objRange = m_objSheet.get_Range("A1", "C1");
m_objRange.set_Value(m_objOpt,objHeaders);
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Create an array with 3 columns and 100 rows and add it to
// the worksheet starting at cell A2.
object[,] objData = new Object[100,3];
Random rdm = new Random((int)DateTime.Now.Ticks);
double nOrderAmt, nTax;
for(int r=0;r<100;r++)
{
objData[r,0] = "ORD" + r.ToString("0000");
nOrderAmt = rdm.Next(1000);
objData[r,1] = nOrderAmt.ToString("c");
nTax = nOrderAmt*0.07;
objData[r,2] = nTax.ToString("c");
}
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange = m_objRange.get_Resize(100,3);
m_objRange.set_Value(m_objOpt,"objData");
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
}
private void Automation_ADORecordset()
{
// Create a Recordset from all the records in the Orders table.
ADODB.Connection objConn = new ADODB.Connection();
ADODB._Recordset objRS = null;
objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", "", "", 0);
objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
object objRecAff;
objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff,
(int)ADODB.CommandTypeEnum.adCmdTable);
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
// Get the Fields collection from the recordset and determine
// the number of fields (or columns).
System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
int nFields = objRS.Fields.Count;
// Create an array for the headers and add it to the
// worksheet starting at cell A1.
object[] objHeaders = new object[nFields];
ADODB.Field objField = null;
for(int n=0;n<nFields;n++)
{
objFields.MoveNext();
objField = (ADODB.Field)objFields.Current;
objHeaders[n] = objField.Name;
}
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange = m_objRange.get_Resize(1, nFields);
m_objRange.set_Value(m_objOpt,objHeaders);
m_objFont = m_objRange.Font;
m_objFont.Bold=true;
// Transfer the recordset to the worksheet starting at cell A2.
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
//Close the recordset and connection
objRS.Close();
objConn.Close();
}
private void Automation_QueryTable()
{
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Create a QueryTable that starts at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objQryTables = m_objSheet.QueryTables;
m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
"OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", m_objRange, "Select * From Orders");
m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
m_objQryTable.Refresh(false);
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
}
private void Use_Clipboard()
{
// Copy a string to the clipboard.
string sData = "FirstName\tLastName\tBirthdate\r\n" +
"Bill\tBrown\t2/5/85\r\n" +
"Joe\tThomas\t1/1/91";
System.Windows.Forms.Clipboard.SetDataObject(sData);
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
// Paste the data starting at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objSheet.Paste(m_objRange, false);
// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
}
private void Create_TextFile()
{
// Connect to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
objConn.Open();
// Execute a command to retrieve all records from the Employees table.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand(
"Select * From Employees", objConn);
System.Data.OleDb.OleDbDataReader objReader;
objReader = objCmd.ExecuteReader();
// Create the FileStream and StreamWriter object to write
// the recordset contents to file.
System.IO.FileStream fs = new System.IO.FileStream(
m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
System.IO.StreamWriter sw = new System.IO.StreamWriter(
fs, System.Text.Encoding.Unicode);
// Write the field names (headers) as the first line in the text file.
sw.WriteLine(objReader.GetName(0) + "\t" + objReader.GetName(1) +
"\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
"\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));
// Write the first six columns in the recordset to a text file as
// tab-delimited.
while(objReader.Read())
{
for(int i=0;i<=5;i++)
{
if(!objReader.IsDBNull(i))
{
string s;
s = objReader.GetDataTypeName(i);
if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
{
sw.Write(objReader.GetInt32(i).ToString());
}
else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
{
sw.Write(objReader.GetDateTime(i).ToString("d"));
}
else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
{
sw.Write(objReader.GetString(i));
}
}
if(i<5) sw.Write("\t");
}
sw.WriteLine();
}
sw.Flush(); // Write the buffered data to the FileStream.
// Close the FileStream.
fs.Close();
// Close the reader and the connection.
objReader.Close();
objConn.Close();
// ==================================================================
// Optionally, automate Excel to open the text file and save it in the
// Excel workbook format.
// Open the text file in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1,
Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
false, true, false, false, false, false, m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook = m_objExcel.ActiveWorkbook;
// Save the text file in the typical workbook format and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal,
m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();
}
private void Use_ADONET()
{
// Establish a connection to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
"Book7.xls;Extended Properties=Excel 8.0;");
objConn.Open();
// Add two records to the table named 'MyTable'.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Bill', 'Brown')";
objCmd.ExecuteNonQuery();
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Joe', 'Thomas')";
objCmd.ExecuteNonQuery();
// Close the connection.
objConn.Close();
}
} // End Class
}// End namespace
Nota È necessario modificare il codice in Visual Studio 2005. Per
impostazione predefinita, in Visual C# viene aggiunto un form al progetto
quando si crea un progetto Windows Form. Il nome del form è Form1. I due file
che rappresentano il form sono denominati Form1.cs e Form1.designer.cs. Il
codice viene scritto in Form1.cs. Nel file Form1.designer.cs Progettazione
Windows Form scrive il codice che implementa tutte le azioni eseguite
trascinando e rilasciando i controlli dalla Casella degli strumenti.
Per ulteriori informazioni su Progettazione Windows Form in Visual C#
2005, visitare il seguente sito Web Microsoft Developer Network (informazioni
in lingua inglese):
Nota Se Office non è stato installato nella cartella predefinita,
C:\Programmi\Microsoft Office, è necessario modificare la costante m_strNorthwind nell'esempio di codice in modo che corrisponda al percorso di
installazione di Northwind.mdb.
Aggiungere quanto segue alle istruzioni Using in Form1.cs:
using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.
Lasciare un commento su queste informazioni
Queste informazioni hanno risolto il problema?
Sì
No
Non so
Queste informazioni erano pertinenti?
Sì
No
In che modo possiamo migliorarle?
Per salvaguardare la privacy, non includere informazioni personali nei commenti.
Grazie. I commenti e suggerimenti forniti verranno utilizzati per migliorare la qualità dei contenuti di supporto tecnico. Per ulteriori opzioni di assistenza, visitare la home page del Supporto Tecnico Microsoft.