70 votes

Comment lire les données d'un fichier Excel en utilisant C# ?

Comment lire un fichier Excel en utilisant C# ? J'ouvre un fichier Excel pour le lire et le copier dans le presse-papiers pour rechercher le format email, mais je ne sais pas comment faire.

FileInfo finfo;
Excel.ApplicationClass ExcelObj = new Excel.ApplicationClass();
ExcelObj.Visible = false;

Excel.Workbook theWorkbook;
Excel.Worksheet worksheet;

if (listView1.Items.Count > 0)
{
    foreach (ListViewItem s in listView1.Items)
    {
        finfo = new FileInfo(s.Text);
        if (finfo.Extension == ".xls" || finfo.Extension == ".xlsx" || finfo.Extension == ".xlt" || finfo.Extension == ".xlsm" || finfo.Extension == ".csv")
        {
            theWorkbook = ExcelObj.Workbooks.Open(s.Text, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, false, false);

            for (int count = 1; count <= theWorkbook.Sheets.Count; count++)
            {
                worksheet = (Excel.Worksheet)theWorkbook.Worksheets.get_Item(count);
                worksheet.Activate();
                worksheet.Visible = false;
                worksheet.UsedRange.Cells.Select();
            }
        }
    }
}

0 votes

Les nouveaux utilisateurs à la recherche d'une solution pourraient vouloir voir cela. filetage .

89voto

Chris Points 3290

OK,

L'un des concepts les plus difficiles à comprendre en matière de programmation Excel VSTO est qu'il ne faut pas se référer aux cellules comme à un tableau, Worksheet[0][0] ne vous donnera pas la cellule A1, il se trompera sur vous. Même lorsque vous tapez dans A1 lorsque Excel est ouvert, vous saisissez en fait des données dans la plage A1. C'est pourquoi les cellules sont appelées "plages nommées". Voici un exemple :

Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet; 
Excel.Range range = sheet.get_Range("A1", Missing.Value)

Vous pouvez maintenant taper littéralement :

range.Text // this will give you the text the user sees
range.Value2 // this will give you the actual value stored by Excel (without rounding)

Si vous voulez faire quelque chose comme ça :

Excel.Range range = sheet.get_Range("A1:A5", Missing.Value)

if (range1 != null)
     foreach (Excel.Range r in range1)
     {
         string user = r.Text
         string value = r.Value2

     }

Il existe peut-être une meilleure méthode, mais celle-ci a fonctionné pour moi.

La raison pour laquelle vous devez utiliser Value2 et non Value c'est parce que le Value est une propriété paramétrée et C# ne les prend pas encore en charge.

Pour ce qui est du code de nettoyage, je le posterai demain en arrivant au travail, je n'ai pas le code avec moi, mais c'est très banal. Il suffit de fermer et de libérer les objets dans l'ordre inverse de leur création. Vous ne pouvez pas utiliser un Using() parce que l'application Excel ou le classeur Excel n'implémente pas l'outil de gestion des données. IDisposable et si vous ne faites pas le ménage, vous vous retrouverez avec des objets Excel en mémoire.

Note :

  • Si vous ne définissez pas l'option Visibility La propriété Excel ne s'affiche pas, ce qui peut être déconcertant pour vos utilisateurs, mais si vous voulez simplement extraire les données, c'est probablement suffisant.
  • Vous pouvez utiliser OleDb, cela fonctionnera aussi.

J'espère que cela vous aidera à démarrer, faites-moi savoir si vous avez besoin d'autres précisions. Je vais poster une

voici un échantillon complet :

using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using ExcelTools = Ms.Office;
using Excel = Microsoft.Office.Interop.Excel;

namespace Tests
{
    [TestFixture]
    public class ExcelSingle
    {
        [Test]
        public void ProcessWorkbook()
        {
            string file = @"C:\Users\Chris\Desktop\TestSheet.xls";
            Console.WriteLine(file);

            Excel.Application excel = null;
            Excel.Workbook wkb = null;

            try
            {
                excel = new Excel.Application();

                wkb = ExcelTools.OfficeUtil.OpenBook(excel, file);

                Excel.Worksheet sheet = wkb.Sheets["Data"] as Excel.Worksheet;

                Excel.Range range = null;

                if (sheet != null)
                    range = sheet.get_Range("A1", Missing.Value);

                string A1 = String.Empty;

                if( range != null )
                    A1 = range.Text.ToString();

                Console.WriteLine("A1 value: {0}", A1);

            }
            catch(Exception ex)
            {
                //if you need to handle stuff
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (wkb != null)
                    ExcelTools.OfficeUtil.ReleaseRCM(wkb);

                if (excel != null)
                    ExcelTools.OfficeUtil.ReleaseRCM(excel);
            }
        }
    }
}

Je posterai les fonctions d'ExcelTools demain, je n'ai pas ce code avec moi non plus.

Modifier : Comme promis, voici les fonctions d'ExcelTools dont vous pourriez avoir besoin.

public static Excel.Workbook OpenBook(Excel.Application excelInstance, string fileName, bool readOnly, bool editable,
        bool updateLinks) {
        Excel.Workbook book = excelInstance.Workbooks.Open(
            fileName, updateLinks, readOnly,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing);
        return book;
    }

public static void ReleaseRCM(object o) {
        try {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
        } catch {
        } finally {
            o = null;
        }
    }

Pour être franc, ce truc est beaucoup plus facile si vous utilisez VB.NET. C'est en C# parce que je ne l'ai pas écrit. VB.NET fait bien les paramètres d'option, C# ne le fait pas, d'où le Type.Missing. Une fois que vous avez tapé Type.Missing deux fois de suite, vous vous enfuyez de la pièce en hurlant !

Pour répondre à votre question, vous pouvez essayer de suivre :

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.find(VS.80).aspx

Je posterai un exemple lorsque je rentrerai de ma réunion... Merci.

Edit : Voici un exemple

range = sheet.Cells.Find("Value to Find",
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Excel.XlSearchDirection.xlNext,
                                                 Type.Missing,
                                                 Type.Missing, Type.Missing);

range.Text; //give you the value found

Voici un autre exemple inspiré de ce qui précède site :

 range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing);

Il est utile de comprendre les paramètres.

P.S. Je suis une de ces personnes bizarres qui aiment apprendre l'automatisation de COM. Tout ce code provient d'un outil que j'ai écrit pour mon travail et qui me demandait de traiter plus de 1000 feuilles de calcul du laboratoire chaque lundi.

0 votes

Je veux lire un fichier excel à partir de Listview pour rechercher l'identifiant de l'email à partir du fichier excel.... j'essaie de le faire...mais je ne connais pas le type d'encodage d'excel, je veux dire les dataformates... comment puis-je lire un fichier excel pour rechercher l'identifiant de l'email...je ne veux pas utiliser la connexion de données

0 votes

+Je viens de perdre tous les noms et dates de plus de 400 fichiers xls sur un disque dur récupéré, et cette réponse m'a remis sur les rails en une heure.

1 votes

Pourquoi la ligne de déclaration "using ExcelTools = Ms.Office ;" dit "The type or namespace name 'Ms' could not be found" ?

21voto

Aashish Points 3842

Vous pouvez utiliser Microsoft.Office.Interop.Excel assemblage pour traiter les fichiers excel.

  1. Cliquez à droite sur votre projet et allez dans Add reference . Ajouter l'assemblage Microsoft.Office.Interop.Excel.
  2. Inclure using Microsoft.Office.Interop.Excel; d'utiliser l'assemblage.

Voici l'exemple de code :

    using Microsoft.Office.Interop.Excel;

    //create the Application object we can use in the member functions.
    Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application();
    _excelApp.Visible = true;

    string fileName = "C:\\sampleExcelFile.xlsx";

    //open the workbook
    Workbook workbook = _excelApp.Workbooks.Open(fileName,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing);

    //select the first sheet        
    Worksheet worksheet = (Worksheet)workbook.Worksheets[1];

    //find the used range in worksheet
    Range excelRange = worksheet.UsedRange;

    //get an object array of all of the cells in the worksheet (their values)
    object[,] valueArray = (object[,])excelRange.get_Value(
                XlRangeValueDataType.xlRangeValueDefault);

    //access the cells
    for (int row = 1;  row <= worksheet.UsedRange.Rows.Count; ++row)
    {
        for (int col = 1; col <= worksheet.UsedRange.Columns.Count; ++col)
        {
            //access each cell
            Debug.Print(valueArray[row, col].ToString());
        }
    }

    //clean up stuffs
    workbook.Close(false, Type.Missing, Type.Missing);
    Marshal.ReleaseComObject(workbook);

    _excelApp.Quit();
    Marshal.FinalReleaseComObject(_excelApp);

0 votes

J'ai découvert que les objets COM suivants doivent être déclarés et ensuite ReleaseComObject() pendant clean up stuffs sinon j'ai un exe Excel zombie qui tourne après la fin du code : Le site Workbooks créé sur _excelApp.Workbooks El Worksheets créé sur workbook.Worksheets , Range les objets créés sur worksheet.UsedRange.Rows y worksheet.UsedRange.Columns et le excelRange objet. Aussi je pense que remplacer les deux worksheet.UsedRange usages avec excelRange au cas où d'autres objets COM seraient créés sans utiliser la variable existante.

17voto

Pourquoi ne pas créer OleDbConnection ? Il y a beaucoup de ressources disponibles sur Internet. Jetez un coup d'oeil à ceci :

http://blog.brezovsky.net/en-text-38.html

2 votes

Un problème que j'ai rencontré avec OleDbConnection (en utilisant l'adaptateur de données Oracle) concernait une colonne contenant à la fois des chiffres et du texte. J'ai obtenu une DataTable avec la colonne formatée en nombre, mais il manquait toutes les cellules où les données étaient formatées en texte. Ma solution était d'utiliser l'interopérabilité pour convertir toute la plage utilisée de la colonne au format TEXTE avant d'utiliser OleDBC pour obtenir les données.

0 votes

Dernières archives de travail aquí . Seulement 40 lignes vous pouvez probablement modifier le message et les ajouter. haussement d'épaules

5voto

Hoghweed Points 1263

Tout d'abord, il est important de savoir ce que vous entendez par "ouvrir un fichier Excel pour le lire et le copier dans le presse-papiers...".

C'est très important, car il existe de nombreuses façons de procéder en fonction de ce que vous avez l'intention de faire. Laissez-moi vous expliquer :

  1. Si vous voulez lire un ensemble de données et le copier dans le presse-papiers et que vous connaissez le format des données (par exemple, les noms des colonnes), je vous suggère d'utiliser un fichier de type OleDbConnection pour ouvrir le fichier, de cette façon vous pouvez traiter le contenu du fichier xls comme une table de base de données, vous pouvez donc lire les données avec une instruction SQL et traiter les données comme vous le souhaitez.

  2. Si vous souhaitez effectuer des opérations sur les données avec le modèle d'objet Excel, ouvrez-le de la manière dont vous avez commencé.

  3. Il est parfois possible de traiter un fichier xls comme une sorte de fichier csv, il existe des outils comme Aides de fichiers qui vous permettent de traiter et d'ouvrir un fichier xls de manière simple en mappant une structure sur un objet arbitraire.

Un autre point important est de savoir dans quelle version d'Excel se trouve le fichier.

J'ai, malheureusement je le dis, une forte expérience de travail avec l'automatisation d'Office dans tous les sens, même si elle est limitée à des concepts comme l'automatisation des applications, la gestion des données et les plugins, et généralement je ne suggère qu'en dernier recours, d'utiliser l'automatisation d'Excel ou d'Office pour lire des données ; juste s'il n'y a pas de meilleures façons d'accomplir cette tâche.

Travailler avec l'automatisation peut être lourd en termes de performance, en termes de coût de ressources, peut impliquer d'autres problèmes liés par exemple à la sécurité et plus encore, et enfin, travailler avec l'interopérabilité COM n'est pas si "gratuit" . Ma suggestion est donc de réfléchir et d'analyser la situation en fonction de vos besoins, puis de choisir la meilleure solution.

2voto

Jake745 Points 699

Utilisez la connexion OLEDB pour communiquer avec les fichiers Excel. Cela donne un meilleur résultat.

using System.Data.OleDb;

                string physicalPath = "Your Excel file physical path";
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataSet ds = new DataSet();
                String strNewPath = physicalPath;
                String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
                String query = "SELECT * FROM [Sheet1$]"; // You can use any different queries to get the data from the excel sheet
                OleDbConnection conn = new OleDbConnection(connString);
                if (conn.State == ConnectionState.Closed) conn.Open();
                try
                {
                    cmd = new OleDbCommand(query, conn);
                    da = new OleDbDataAdapter(cmd);
                    da.Fill(ds);

                }
                catch
                {
                    // Exception Msg 

                }
                finally
                {
                    da.Dispose();
                    conn.Close();
                }

Les données de sortie seront stockées dans le jeu de données, en utilisant l'objet jeu de données, vous pouvez facilement accéder aux données. J'espère que cela pourra vous aider.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X