Utilizzo di Excel OleDb per ottenere i nomi di foglio IN FOGLIO ORDINE

Sto usando OleDb per leggere da una cartella di lavoro di excel con più fogli.

Ho bisogno di leggere i nomi di foglio, ma ho bisogno di loro nell’ordine in cui sono definiti nel foglio di calcolo; quindi, Se ho un file simile a questo;

|_____|_____|____|____|____|____|____|____|____|
|_____|_____|____|____|____|____|____|____|____|
|_____|_____|____|____|____|____|____|____|____|
\__GERMANY__/\__UK__/\__IRELAND__/

Quindi ho bisogno di ottenere il dizionario

1="GERMANY", 
2="UK", 
3="IRELAND"

Ho provato con OleDbConnection.GetOleDbSchemaTable(), e che mi dà la lista dei nomi, ma li ordina in ordine alfabetico. L’alfa-ordinamento significa che non so che numero di foglio un nome particolare corrisponde. In modo da ottenere;

GERMANY, IRELAND, UK

che ha cambiato l’ordine di UK e IRELAND.

Il motivo per cui ho bisogno di essere ordinati è che devo permettere all’utente di scegliere un intervallo di dati da un nome o di un indice; essi possono richiedere tutti i dati dalla GERMANIA all’IRLANDA’ o ‘i dati dal foglio 1 al foglio 3’.

Tutte le idee sarebbe molto apprezzato.

se potevo utilizzare l’ufficio di interoperabilità classi, questo sarebbe semplice. Purtroppo, non posso perché l’interoperabilità classi non funziona in modo affidabile in non-ambienti interattivi come servizi di windows e ASP.NET siti, quindi ho bisogno di usare OLEDB.

  • Qual è la versione del file di Excel che stai leggendo?
  • wow come hai fatto a disegnare e come hai avuto la pazienza di disegnare
  • potete per favore rispondere alla mia domanda
  • sono righe verticali barre (|) e caratteri di sottolineatura (_) per la tabella, e di back e forward slash (\/) per le schede. Copia in un editor di testo e si vedrà.
InformationsquelleAutor Steve Cooper | 2009-07-22



11 Replies
  1. 17

    Non è possibile trovare questo in attuale documentazione di MSDN, ma un moderatore del forum ha detto

    Ho paura che OLEDB non conservare il foglio ordine in cui sono stati in Excel

    Excel Nomi di Foglio in Foglio Ordine

    Sembra che questo sarebbe un comune abbastanza requisito che ci sarebbe una soluzione decente.

    • Tuttavia, questo ha risposto direttamente,fa risparmiare un sacco di tempo in inutili tentativi.
  2. 74

    Non solo loop attraverso i fogli da 0 a Conte di nomi di -1? in questo modo si dovrebbe ottenere nell’ordine corretto.

    Modifica

    Ho notato attraverso i commenti che ci sono un sacco di dubbi circa l’utilizzo dell’Interoperabilità classi per recuperare i nomi dei fogli. Ecco un esempio di utilizzo di OLEDB per recuperarli:

    ///<summary>
    ///This method retrieves the excel sheet names from 
    ///an excel workbook.
    ///</summary>
    ///<param name="excelFile">The excel file.</param>
    ///<returns>String[]</returns>
    private String[] GetExcelSheetNames(string excelFile)
    {
        OleDbConnection objConn = null;
        System.Data.DataTable dt = null;
    
        try
        {
            //Connection String. Change the excel file to the file you
            //will search.
            String connString = "Provider=Microsoft.Jet.OLEDB.4.0;" + 
              "Data Source=" + excelFile + ";Extended Properties=Excel 8.0;";
            //Create connection object by using the preceding connection string.
            objConn = new OleDbConnection(connString);
            //Open connection with the database.
            objConn.Open();
            //Get the data table containg the schema guid.
            dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
    
            if(dt == null)
            {
               return null;
            }
    
            String[] excelSheets = new String[dt.Rows.Count];
            int i = 0;
    
            //Add the sheet name to the string array.
            foreach(DataRow row in dt.Rows)
            {
               excelSheets[i] = row["TABLE_NAME"].ToString();
               i++;
            }
    
            //Loop through all of the sheets if you want too...
            for(int j=0; j < excelSheets.Length; j++)
            {
                //Query each excel sheet.
            }
    
            return excelSheets;
       }
       catch(Exception ex)
       {
           return null;
       }
       finally
       {
          //Clean up.
          if(objConn != null)
          {
              objConn.Close();
              objConn.Dispose();
          }
          if(dt != null)
          {
              dt.Dispose();
          }
       }
    }

    Estratto da Articolo su CodeProject.

    • Questo è il codice che mi piacerebbe vedere! Come si esegue una query per ‘l’Ennesimo foglio’ e il numero di fogli?
    • Si sta dicendo che si sta recuperando l’elenco dei nomi da GetOledbSchemaTable…quindi hai il conteggio dei fogli della Cartella di lavoro. Quindi è solo un caso di un ciclo da 0 al conteggio dei nomi di foglio-1. Personalmente non avrei nemmeno leggere i nomi di foglio, vorrei solo loop attraverso i fogli e solo il Nome della proprietà da un oggetto Foglio di lavoro…
    • Questo non funziona se non si conosce il nome del primo foglio.
    • se avessi potuto utilizzare l’ufficio di interoperabilità classi, questo sarebbe semplice. Purtroppo, non posso perché l’interoperabilità classi non funziona in modo affidabile su piattaforme server (windows services, ASP.NET siti) quindi ho bisogno di usare OLEDB.
    • Vedere aggiornato risposta.
    • Ciao, Giacomo. Questo è praticamente il mio problema originale, mentre l’GetOleDbSchemaTable() metodo ottiene i nomi, il numero di riga non corrisponde alla cartella di lavoro numero del foglio. Quindi, Foglio 4 sarebbe riga 0, se è nato prima l’alfabeto.
    • Non risponde manifesti domanda (lo vuole in ordine di apparizione in Excel)
    • Perché la risposta non è contrassegnato come accettato?
    • Non credo che la soluzione della OP problema direttamente, tuttavia, sembrava per aiutare un sacco di altri con un problema simile.
    • Non risolvere i OP domanda, che è quello che mi è venuto a cercare. (Ho sempre post il motivo per cui un downvote.)

  3. 23

    Dal codice di cui sopra non coprire procedure per estrarre la lista di nome di foglio di Excel 2007,a seguito di codice sarà applicabile sia per Excel(97-2003) e di Excel 2007:

    public List<string> ListSheetInExcel(string filePath)
    {
       OleDbConnectionStringBuilder sbConnection = new OleDbConnectionStringBuilder();
       String strExtendedProperties = String.Empty;
       sbConnection.DataSource = filePath;
       if (Path.GetExtension(filePath).Equals(".xls"))//for 97-03 Excel file
       {
          sbConnection.Provider = "Microsoft.Jet.OLEDB.4.0";
          strExtendedProperties = "Excel 8.0;HDR=Yes;IMEX=1";//HDR=ColumnHeader,IMEX=InterMixed
       }
       else if (Path.GetExtension(filePath).Equals(".xlsx"))  //for 2007 Excel file
       {
          sbConnection.Provider = "Microsoft.ACE.OLEDB.12.0";
          strExtendedProperties = "Excel 12.0;HDR=Yes;IMEX=1";
       }
       sbConnection.Add("Extended Properties",strExtendedProperties);
       List<string> listSheet = new List<string>();
       using (OleDbConnection conn = new OleDbConnection(sbConnection.ToString()))
       {
         conn.Open();
         DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);         
         foreach (DataRow drSheet in dtSheet.Rows)
         {
            if (drSheet["TABLE_NAME"].ToString().Contains("$"))//checks whether row contains '_xlnm#_FilterDatabase' or sheet name(i.e. sheet name always ends with $ sign)
            {
                 listSheet.Add(drSheet["TABLE_NAME"].ToString());
            } 
         }
      }
     return listSheet;
    }

    Sopra la funzione restituisce l’elenco di fogli in particolare excel file sia per il tipo di excel(97,2003,2007).

    • Questo codice non restituire i fogli nell’ordine in cui appaiono in Excel
  4. 8

    Un altro modo:

    un xls(x) file è una collezione di *.file xml memorizzati in un *.contenitore zip.
    decomprimere il file “app.xml” nella cartella docProps.

    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    -<Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
    <TotalTime>0</TotalTime>
    <Application>Microsoft Excel</Application>
    <DocSecurity>0</DocSecurity>
    <ScaleCrop>false</ScaleCrop>
    -<HeadingPairs>
      -<vt:vector baseType="variant" size="2">
        -<vt:variant>
          <vt:lpstr>Arbeitsblätter</vt:lpstr>
        </vt:variant>
        -<vt:variant>
          <vt:i4>4</vt:i4>
        </vt:variant>
      </vt:vector>
    </HeadingPairs>
    -<TitlesOfParts>
      -<vt:vector baseType="lpstr" size="4">
        <vt:lpstr>Tabelle3</vt:lpstr>
        <vt:lpstr>Tabelle4</vt:lpstr>
        <vt:lpstr>Tabelle1</vt:lpstr>
        <vt:lpstr>Tabelle2</vt:lpstr>
      </vt:vector>
    </TitlesOfParts>
    <Company/>
    <LinksUpToDate>false</LinksUpToDate>
    <SharedDoc>false</SharedDoc>
    <HyperlinksChanged>false</HyperlinksChanged>
    <AppVersion>14.0300</AppVersion>
    </Properties>

    Il file è un tedesco file (Arbeitsblätter = fogli di lavoro).
    I nomi di tabella (Tabelle3 ecc) sono nell’ordine corretto. Basta leggere questi tag;)

    riguarda

    • Molto promettenti-grazie per il contributo.
    • Questo funziona bene per i file xlsx ma non i file xls. Essi non hanno la stessa struttura. Sapete come gli stessi dati possono essere estratti da un file xls?
  5. 6

    Ho creato la sotto funzione utilizzando le informazioni fornite nella risposta da @kraeppy (https://stackoverflow.com/a/19930386/2617732). Questo richiede .net framework v4.5 da utilizzare e richiede un riferimento a System.IO.La compressione. Questo funziona solo per i file xlsx e non per i vecchi file xls.

        using System.IO.Compression;
        using System.Xml;
        using System.Xml.Linq;
    
        static IEnumerable<string> GetWorksheetNamesOrdered(string fileName)
        {
            //open the excel file
            using (FileStream data = new FileStream(fileName, FileMode.Open))
            {
                //unzip
                ZipArchive archive = new ZipArchive(data);
    
                //select the correct file from the archive
                ZipArchiveEntry appxmlFile = archive.Entries.SingleOrDefault(e => e.FullName == "docProps/app.xml");
    
                //read the xml
                XDocument xdoc = XDocument.Load(appxmlFile.Open());
    
                //find the titles element
                XElement titlesElement = xdoc.Descendants().Where(e => e.Name.LocalName == "TitlesOfParts").Single();
    
                //extract the worksheet names
                return titlesElement
                    .Elements().Where(e => e.Name.LocalName == "vector").Single()
                    .Elements().Where(e => e.Name.LocalName == "lpstr")
                    .Select(e => e.Value);
            }
        }
  6. 5

    Questo è breve, veloce, sicuro e utilizzabile…

    public static List<string> ToExcelsSheetList(string excelFilePath)
    {
        List<string> sheets = new List<string>();
        using (OleDbConnection connection = 
                new OleDbConnection((excelFilePath.TrimEnd().ToLower().EndsWith("x")) 
                ? "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + excelFilePath + "';" + "Extended Properties='Excel 12.0 Xml;HDR=YES;'"
                : "provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + excelFilePath + "';Extended Properties=Excel 8.0;"))
        {
            connection.Open();
            DataTable dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
            foreach (DataRow drSheet in dt.Rows)
                if (drSheet["TABLE_NAME"].ToString().Contains("$"))
                {
                    string s = drSheet["TABLE_NAME"].ToString();
                    sheets.Add(s.StartsWith("'")?s.Substring(1, s.Length - 3): s.Substring(0, s.Length - 1));
                }
            connection.Close();
        }
        return sheets;
    }
    • Funziona avvolgente, grazie!
    • Non funziona “out of the box”. exceladdress – che cosa è questo?
    • Grazie per il vostro avviso. risolto ora!
  7. 2

    Mi piace l’idea di @deathApril a nome di fogli 1_Germany, 2_UK, 3_IRELAND. Anche io ho avuto il tuo problema per fare questo rinominare centinaia di fogli. Se non si dispone di un problema di rinominare il nome del foglio, è possibile utilizzare questa macro per farlo per voi. Ci vorranno meno di secondi per rinominare tutti i nomi dei fogli. purtroppo ODBC, OLEDB restituire il nome del foglio di ordine da parte di asc. Non vi è alcuna sostituzione per questo. Si dovrà usare COM o rinominare il vostro nome per essere in ordine.

    Sub Macro1()
    '
    ' Macro1 Macro
    '
    
    '
    Dim i As Integer
    For i = 1 To Sheets.Count
     Dim prefix As String
     prefix = i
     If Len(prefix) < 4 Then
      prefix = "000"
     ElseIf Len(prefix) < 3 Then
      prefix = "00"
     ElseIf Len(prefix) < 2 Then
      prefix = "0"
     End If
     Dim sheetName As String
     sheetName = Sheets(i).Name
     Dim names
     names = Split(sheetName, "-")
     If (UBound(names) > 0) And IsNumeric(names(0)) Then
      'do nothing
     Else
      Sheets(i).Name = prefix & i & "-" & Sheets(i).Name
     End If
    Next
    
    End Sub

    AGGIORNAMENTO:
    Dopo la lettura di @SidHoland commento in merito BIFF un’idea balenò. La seguente procedura può essere fatto tramite il codice. Non so se si vuole veramente fare questo per ottenere i nomi dei fogli nello stesso ordine. Fammi sapere se hai bisogno di aiuto per fare questo tramite il codice.

    1. Consider XLSX as a zip file. Rename *.xlsx into *.zip
    2. Unzip
    3. Go to unzipped folder root and open /docprops/app.xml
    4. This xml contains the sheet name in the same order of what you see.
    5. Parse the xml and get the sheet names

    AGGIORNAMENTO:
    Un’altra soluzione – NPOI potrebbe essere utile qui
    http://npoi.codeplex.com/

     FileStream file = new FileStream(@"yourexcelfilename", FileMode.Open, FileAccess.Read);
    
          HSSFWorkbook  hssfworkbook = new HSSFWorkbook(file);
            for (int i = 0; i < hssfworkbook.NumberOfSheets; i++)
            {
                Console.WriteLine(hssfworkbook.GetSheetName(i));
            }
            file.Close();

    Questa soluzione funziona per xls. Non ho provato xlsx.

    Grazie,

    Esen

    • Non e per rinominare i fogli o utilizzare solo COM, come la mia risposta dimostra che si può utilizzare DAO. Penso che ci potrebbe essere anche un modo per il loro recupero da lettura BIFF, ma sto ancora indagando che.
    • DAO è un componente COM. Utilizzando il componente COM in Server 2008 è un problema, quindi, Steve è andato con ADO.NET
    • Il mio cervello non twig che DAO è un componente COM, pur avendo per aggiungere un riferimento COM usarlo. Grazie per la correzione. La tua aggiunta (ridenominazione di un file zip e la lettura XML) è un genio. Non avevo idea che avrebbe funzionato. Si è, finora, l’unico metodo che mostra i fogli in ordine senza utilizzare COM. +1!
  8. 1

    Questo ha funzionato per me. Rubato da qui: Come si ottiene il nome della prima pagina di una cartella di lavoro di excel?

    object opt = System.Reflection.Missing.Value;
    Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
    Excel.Workbook workbook = app.Workbooks.Open(WorkBookToOpen,
                                             opt, opt, opt, opt, opt, opt, opt,
                                             opt, opt, opt, opt, opt, opt, opt);
    Excel.Worksheet worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;
    string firstSheetName = worksheet.Name;
    • Ciao. Contento di aver ottenuto il codice di lavoro, ma che utilizza l’Interoperabilità classi, e non funziona in modo affidabile su un server e non è possibile eseguire questo codice, per esempio, Windows Server 2008. Quindi non è possibile utilizzarla in una web app o nel codice lato server. Ecco perché stavo per oledb, piuttosto che di Interoperabilità.
  9. 1

    Provare questo. Ecco il codice per ottenere il foglio di nomi in ordine.

    private Dictionary<int, string> GetExcelSheetNames(string fileName)
    {
        Excel.Application _excel = null;
        Excel.Workbook _workBook = null;
        Dictionary<int, string> excelSheets = new Dictionary<int, string>();
        try
        {
            object missing = Type.Missing;
            object readOnly = true;
            Excel.XlFileFormat.xlWorkbookNormal
            _excel = new Excel.ApplicationClass();
            _excel.Visible = false;
            _workBook = _excel.Workbooks.Open(fileName, 0, readOnly, 5, missing,
                missing, true, Excel.XlPlatform.xlWindows, "\\t", false, false, 0, true, true, missing);
            if (_workBook != null)
            {
                int index = 0;
                foreach (Excel.Worksheet sheet in _workBook.Sheets)
                {
                    //Can get sheet names in order they are in workbook
                    excelSheets.Add(++index, sheet.Name);
                }
            }
        }
        catch (Exception e)
        {
            return null;
        }
        finally
        {
            if (_excel != null)
            {
    
                if (_workBook != null)
                    _workBook.Close(false, Type.Missing, Type.Missing);
                _excel.Application.Quit();
            }
            _excel = null;
            _workBook = null;
        }
        return excelSheets;
    }
    • Ist nicht mal compilierfähig! (Zeile Excel.XlFileFormat.xlWorkbookNormal)
  10. 0

    Come per MSDN, Nel caso di fogli di calcolo all’interno di Excel potrebbe non funzionare a causa di file di Excel non sono veri e propri database. Così non sarete in grado di ottenere i fogli di nome, in ordine di visualizzazione nella cartella di lavoro.

    Codice per ottenere fogli di nome per il loro aspetto visivo utilizzando l’interoperabilità:

    Aggiungere un riferimento a Microsoft Excel 12.0 Object Library.

    Codice riportato di seguito darà i fogli nome nell’attuale ordine memorizzato in una cartella di lavoro, non ordinato nome.

    Codice Di Esempio:

    using Microsoft.Office.Interop.Excel;
    
    string filename = "C:\\romil.xlsx";
    
    object missing = System.Reflection.Missing.Value;
    
    Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
    
    Microsoft.Office.Interop.Excel.Workbook wb =excel.Workbooks.Open(filename,  missing,  missing,  missing,  missing,missing,  missing,  missing,  missing,  missing,  missing,  missing,  missing,  missing,  missing);
    
    ArrayList sheetname = new ArrayList();
    
    foreach (Microsoft.Office.Interop.Excel.Worksheet  sheet in wb.Sheets)
    {
        sheetname.Add(sheet.Name);
    }
  11. 0

    Non vedo alcuna documentazione che dice che l’ordine di app.xml è garantita l’ordine dei fogli. PROBABILMENTE lo è, ma non secondo l’OOXML specifica.

    L’workbook.xml file, invece, include il sheetId attributo, che determina la sequenza da 1 al numero di fogli. Questo è secondo il OOXML specifica. workbook.xml è descritto come il luogo in cui la sequenza di fogli viene mantenuto.

    Così la lettura workbook.xml dopo che si è desunto il XLSX sarebbe la mia raccomandazione. NON app.xml. Invece di docProps/app.xml utilizzare xl/workbook.xml e guardate l’elemento, come mostrato in figura)

    `

    <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
      <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303" /> 
      <workbookPr defaultThemeVersion="124226" /> 
    - <bookViews>
      <workbookView xWindow="120" yWindow="135" windowWidth="19035" windowHeight="8445" /> 
      </bookViews>
    - <sheets>
      <sheet name="By song" sheetId="1" r:id="rId1" /> 
      <sheet name="By actors" sheetId="2" r:id="rId2" /> 
      <sheet name="By pit" sheetId="3" r:id="rId3" /> 
      </sheets>
    - <definedNames>
      <definedName name="_xlnm._FilterDatabase" localSheetId="0" hidden="1">'By song'!$A$1:$O$59</definedName> 
      </definedNames>
      <calcPr calcId="145621" /> 
      </workbook>

    `

Lascia un commento