DataGrid в Excel? - PullRequest
       1

DataGrid в Excel?

4 голосов
/ 24 марта 2012

У меня есть программа, созданная в WPF. Он отображает DataGrid с данными из базы данных MySQL. Я хочу разрешить пользователю экспортировать содержимое DataGrid в файл Excel. Это возможно с WPF?

Когда я использую метод, показанный здесь: https://www.outcoldman.ru/en/blog/show/201

Единственная строка, которая импортируется в файл xls, - это заголовок.

Ответы [ 5 ]

6 голосов
/ 24 марта 2012

Я также искал что-то подобное, чтобы помочь экспортировать данные из таблицы данных в Excel, но не нашел ничего, что работает. В конце концов я просто преобразовал содержимое DataGrid в двумерный массив строк и экспортировал его с помощью взаимодействия dll.

Код выглядит примерно так:

    Excel.Application xlApp;
    Excel.Workbook xlWorkBook;
    Excel.Worksheet xlWorkSheet;
    object misValue = System.Reflection.Missing.Value;
    Excel.Range rangeToHoldHyperlink;
    Excel.Range CellInstance;
    xlApp = new Excel.Application();
    xlWorkBook = xlApp.Workbooks.Add(misValue);

    xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
    xlApp.DisplayAlerts = false;
    //Dummy initialisation to prevent errors.
    rangeToHoldHyperlink = xlWorkSheet.get_Range("A1", Type.Missing);
    CellInstance = xlWorkSheet.get_Range("A1", Type.Missing);

    for (int i = 0; i < NumberOfCols; i++)
    {
            for (int j = 0; j <= NumberOfRows; j++)
            {
                xlWorkSheet.Cells[j + 1, i + 1] = DataToWrite[j][i];
            }
     }

Если вы ищете форматирование, они также поддерживаются в этом. Я хотел добавить гиперссылку, и следующий код делает это:

 CellInstance = xlWorkSheet.Cells[j + 1, i + 1];

                xlWorkSheet.Hyperlinks.Add(
                    CellInstance,
                    DataToWrite[j][i],
                    Type.Missing,
                    "Hover Text Comes Here",
                    "Text to be displayed");

Если вы хотите, чтобы первая строка была заголовком, вы можете выделить их следующим образом:

Excel.Range Range1 = xlWorkSheet.get_Range("A1");
Range1.EntireRow.Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
Range1.EntireRow.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightSkyBlue);
Range1.EntireRow.Font.Size = 14;
Range1.EntireRow.AutoFit();

Наконец, чтобы сохранить Excel в желаемом пути:

xlWorkBook.SaveAs(@FilePath, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close();

Ссылка на взаимодействие добавляется следующим образом:

Right Click on the Project name -> Click "Add reference" -> Goto "COM" tab -> Search for "Microsoft Excel Object Library" click "OK" to add the reference.

Вы должны использовать следующее пространство имен:

using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
2 голосов
/ 24 марта 2012

Вы также можете экспортировать содержимое вашей DataGrid в файл CSV.

Я не знаю, используете ли вы привязку данных, и здесь я предполагаю, что вы делаете.

var items = LoadItemsFromUnderlyingDataStore();
itemsDataGrid.ItemsSource = items;

private void ItemsDataGridExportButton_Click(object sender, EventArgs e) {
    var filename = AutoGenerateDateTimedFileName();
    using (var csv = new FileStream(filename)) {
        // if you want any column header in your Excel file, uncomment line below.            
        //csv.WriteLine("Column1,Column2,Column3,Column4");
        items.ForEach(item => 
            csv.WriteLine("{0},{1},{2},{3}"
                , item.PropertyFromFirstColumn
                , item.PropertyFromSecondColumn
                , item.PropertyFromThirdColumn
                , item.PropertyFromFourthColumn);
        try { csv.Flush(); }
        catch(IOException ex) { 
            // Handle error (log, whatever...)
            throw; // If you need to let the exception bubble up...
        }
    }
}

private string AutoGenerateDateTimedFileName() {
    return string.Format("DataGridExport_{0}_{1}.csv"
        , DataTime.Today.ToShortDateString()
        , DateTime.Now.ToLongTimeString());
}

В итоге, этот пример кода должен делать это с файлами CSV, и вы сможете открыть его с помощью Excel позже.Вы даже можете запустить Excel при создании файла.

private void ItemsDataGridExportButton_Click(object sender, EventArgs e) {
    // here's the upper code sample, and add the following:
    Process.Start(filename)
}

Теперь, используя Excel Interop.

object[,] values = BuildTwoDimensionalMatrixFromDataGridContent();
Worksheet.Cells.Value(Microsoft.Office.Interop.Excel.XlRangeValueDataType.xlRangeValueDefault) = values;

Это, вероятно, самый быстрый способ установки значений в файле Excel, и естьнет итерации по адресу.

Первое предложенное решение с использованием файла CSV, вероятно, является самым простым для понимания и работы с ним.

Отказ от ответственности

Этот код был создан прямо изверхняя часть моей головы и как таковая не была проверена.Для корректной работы этого кода с контекстом вашей программы могут потребоваться некоторые изменения.Кроме того, может потребоваться анализ небольших различий между кодом с показанным здесь взаимодействием и кодом, который вы сможете использовать с WPF.

Возможно, лучшим способом являетсянаписать себе библиотеку классов, которая должна быть развернута вместе с вашим решением, которая была бы написана на простом C #, чтобы вы могли использовать простые инструкции Interop.

2 голосов
/ 24 марта 2012

Эта ссылка может быть полезна для вас-

Экспорт данных в Excel из Silverlight / WPF DataGrid

0 голосов
/ 11 июня 2019
private void data2Exel(DataGrid dataGrid)
        {
            Excel.Application excel = new Excel.Application();
            excel.Visible = true; //www.yazilimkodlama.com
            Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value);
            Worksheet sheet1 = (Worksheet)workbook.Sheets[1];

            for (int j = 0; j < dataGrid.Columns.Count; j++) //Başlıklar için
            {
                Range myRange = (Range)sheet1.Cells[1, j + 1];
                sheet1.Cells[1, j + 1].Font.Bold = true; //Başlığın Kalın olması için
                sheet1.Columns[j + 1].ColumnWidth = 15; //Sütun genişliği ayarı
                myRange.Value2 = dataGrid.Columns[j].Header;
            }
            for (int i = 0; i < dataGrid.Columns.Count; i++)
            {
                for (int j = 0; j < dataGrid.Items.Count; j++)
                {
                    TextBlock b = dataGrid.Columns[i].GetCellContent(dataGrid.Items[j]) as TextBlock;
                    Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[j + 2, i + 1];
                    myRange.Value2 = b.Text;
                }
            }
        }
0 голосов
/ 05 марта 2016

Пример кода извлекает список всех каталогов из C: \ Windows \ WinSxS , связывает его с DataGrid и экспортирует DataGrid в Excel. Главное здесь - знать, что самый быстрый способ экспорта данных в Excel - это присвоение массива рабочему листу. Но проблема в том, что мы не можем получить этот массив напрямую из DataGrid. Таким образом, нам сначала нужно заполнить его. Немного подумав, мы можем получить значения свойств и заполнить массив. Экспорт данных занимает всего одну строку. Папка WinSxS на моем компьютере содержит 14880 каталогов. Код выполняется около 3 секунд (заполнение DataGrid + экспорт).

    using Excel = Microsoft.Office.Interop.Excel;

    private void ExportDataGrid()
    {
        // Fetch directories
        var dirInfo = new DirectoryInfo(@"C:\Windows\WinSxS\");
        var items = dirInfo.EnumerateDirectories();
        dataGrid.ItemsSource = items;
        var source = dataGrid.ItemsSource;

        // Create Excel app
        var excel = new Excel.Application { Visible = true };
        excel.ScreenUpdating = false; //Some speed-up
        var book = excel.Workbooks.Add();
        var sheet = (Excel.Worksheet)book.Sheets[1];

        int row = -1; //The row in array
        Type type = null;

        // Create array to hold data
        int rows = items.Count(), cols = dataGrid.Columns.Count;
        var arr = new object[rows, cols];

        foreach (DirectoryInfo dir_info in dataGrid.ItemsSource)
        {
            ++row;
            // You can also use GetType().GetTypeInfo() as of .NET 4.5+.
            // The return type will be TypeInfo.
            type = dir_info.GetType();
            for (int col = 0; col < cols; ++col)
            {
                var column_name = (string)dataGrid.Columns[col].Header;
                var value = type.GetProperty(column_name).GetValue(dir_info);
                arr.SetValue(value, row, col);
            }
        }

        // Create header
        for (int col = 0; c < cols; ++c)
        {
            sheet.Cells[1, col + 1].Value = dataGrid.Columns[col].Header;
        }

        // Dump array - the fastest way
        sheet.Range["A2"].Resize[rows, cols].Value = arr;

        // Restore screen updating - otherwise Excel will not response to actions
        excel.ScreenUpdating = true;

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...