使用C#將DataTable導出到文件

目錄

背景

助手類

創建純文件內容的擴展方法

創建Excel文件對象的擴展方法

文件助手

使用代碼

創建普通文件

創建Excel文件

解決方案和項目

侷限性

下一步是什麼?


背景

導出的文件類型是什麼?

  • 帶分隔符的純文本文件(擴展名爲.csv.txt.gm等)
  • Excel文件(.xls.xlsx

助手類

創建純文件內容的擴展方法

使用此擴展名,我們將能夠創建普通的文件內容作爲一個string,考慮到一個輸入DataTable

擴展方法還具有以下選項:

  • 設置分隔符
  • 包括列名作爲文件標題行
  • 處理具有默認值的null值列
  • 必要時修剪列值
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

public static class DataTableHelper
{
    public static string DataTableToFileContent(this DataTable datatable, 
                  string seperator = ",", bool inchuleColumnName = true, 
                  string defaultNullColumnValue = "", bool trimColumValue = true)
    {
        /*https://stackoverflow.com/a/28503521 */

        if (defaultNullColumnValue == null)
        {
            throw new NullReferenceException("'defaultNullColumnValue' should not be null");
        }
        StringBuilder sb = new StringBuilder();
        
        /*header*/
        if (inchuleColumnName)
        {
            for (int i = 0; i < datatable.Columns.Count; i++)
            {
                sb.Append(datatable.Columns[i]);
                if (i < datatable.Columns.Count - 1)
                {
                    sb.Append(seperator);
                }
            }
            sb.AppendLine();
        }

        /*data*/
        long lineNo = 0;
        string value;
        foreach (DataRow row in datatable.Rows)
        {
            lineNo++;
            if (lineNo > 1)
            {
                sb.AppendLine();
            }
            for (int i = 0; i < datatable.Columns.Count; i++)
            {
                var columnValue = row[i];
                value = columnValue == DBNull.Value ? 
                        defaultNullColumnValue : columnValue.ToString();
                if (trimColumValue)
                {
                    value = value.Trim();
                }
                sb.Append(value);
                if (i < datatable.Columns.Count - 1)
                {
                    sb.Append(seperator);
                }
            }
        }
        return sb.ToString();
    }
}

創建Excel文件對象的擴展方法

要創建Excel文件內容,我們使用EPPlus。這是一個很棒的庫,具有許多很棒的功能和選項。不幸的是,它從版本5開始不再是免費版本,我們使用的是較低版本的4.5.3.3

擴展方法還具有以下選項:

  • 設置sheet名稱
  • 包括列名稱作爲標題,並自動過濾到標題行
  • 處理具有默認值的null值列
  • 必要時修剪列值
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

public static class DataTableHelper
{
    private static string GetExcelColumnName(int columnNumber)
    {
        /*
        1 equal A
        https://stackoverflow.com/questions/181596/
        how-to-convert-a-column-number-e-g-127-into-an-excel-column-e-g-aa
        */
        int dividend = columnNumber;
        string columnName = String.Empty;
        int modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
            dividend = (int)((dividend - modulo) / 26);
        }

        return columnName;
    }

    public static ExcelPackage DataTableToExcel(this DataTable datatable, 
    string sheetName = "Sheet1",  bool inchuleColumnName = true, 
    string defaultNullColumnValue = null, bool trimColumValue = true)
    {
        if (String.IsNullOrEmpty(sheetName))
        {
            throw new NullReferenceException("'sheetName' should not be null or empty");
        }
        
        sheetName = sheetName.Trim();
        ExcelPackage excel = new ExcelPackage();
        var workSheet = excel.Workbook.Worksheets.Add(sheetName);
        int columnCount = datatable.Columns.Count;
        int lineNo = 1;

        /*header*/
        if (inchuleColumnName)
        {
            int headerNumber = 1;
            foreach (DataColumn column in datatable.Columns)
            {
                workSheet.Cells[lineNo, headerNumber].Value = column.ColumnName;
                headerNumber++;
            }
            workSheet.Row(lineNo).Style.Font.Bold = true;
            /*add filter to header*/
            workSheet.Cells[String.Format("{0}{1}:{2}{3}", GetExcelColumnName(1), 
            lineNo, GetExcelColumnName(columnCount), lineNo)].AutoFilter = true;
            lineNo++;
        }

        /*data*/
        string value;
        foreach (DataRow row in datatable.Rows)
        {
            for (int i = 0; i < columnCount; i++)
            {
                var columnValue = row[i];
                value = columnValue == DBNull.Value ? 
                        defaultNullColumnValue : columnValue.ToString();
                if (trimColumValue && value != null)
                {
                    value = value.Trim();
                }
                int columnNo = i + 1;
                /*https://stackoverflow.com/a/36824090*/
                workSheet.Cells[lineNo, columnNo].Value = 
                                string.IsNullOrEmpty(value) ? null : value;
            }
            lineNo++;
        }

        for (int i = 1; i <= columnCount; i++)
        {
            workSheet.Column(i).AutoFit();
        }
        return excel;
    }
}

讓我們將代碼添加到我們現有的擴展幫助類中。

文件助手

這是一個小的文件/目錄/路徑幫助程序類。在這裏,我們將使用如下方法:

  • DeleteFileIfExists(string filePath) 刪除文件(如果存在)
  • WriteAllText(string filePath, string contents) 在具有特定內容的位置創建一個新文件
using System.IO;

public class FileSystemHelper
{
    /// <summary>
    /// string p1 = "c:\\temp\\";
    /// string p2 = "\\subdir\\file\\";
    /// to c:\temp\subdir\file
    /// </summary>
    public static string CombineDirectory(string rootDirectoryPath, string childDirectoryPath)
    {
        rootDirectoryPath = rootDirectoryPath.TrimEnd('\\');
        childDirectoryPath = childDirectoryPath.Trim('\\');
        return Path.Combine(rootDirectoryPath, childDirectoryPath);
    }

    /// <summary>
    /// string p1 = "c:\\temp\\";
    /// string p2 = "\\file.txt";
    /// to c:\temp\file.txt
    /// </summary>
    public static string CombineFile(string rootDirectoryPath, string filePathOrName)
    {
        rootDirectoryPath = rootDirectoryPath.TrimEnd('\\');
        filePathOrName = filePathOrName.Trim('\\');
        return Path.Combine(rootDirectoryPath, filePathOrName);
    }

    public static void CreateDirectoryIfNotExists(string directoryPath)
    {
        if (!DirectoryExists(directoryPath))
        {
            Directory.CreateDirectory(directoryPath);
        }
    }

    public static void DeleteFileIfExists(string filePath)
    {
        if (FileExists(filePath))
        {
            File.Delete(filePath);
        }
    }

    public static bool DirectoryExists(string directoryPath)
    {
        return Directory.Exists(directoryPath);
    }

    public static bool FileExists(string filePath)
    {
        return File.Exists(filePath);
    }

    /*file*/
    public static void MoveFile(string fromFilePath, string toFilePath)
    {
        File.Move(fromFilePath, toFilePath);
    }

    public static void WriteAllText(string filePath, string contents)
    {
        /*create file if doesn't exist*/
        File.WriteAllText(filePath, contents);
    }
}

其他方法也很有用,因此也請看一看。

使用代碼

創建普通文件

在這裏,我們正在創建一個CSV文件。

string filePath = @"c:\dataTable.csv";
DataTable dataTable = Data.Instance.DataTable;

FileSystemHelper.DeleteFileIfExists(filePath);
FileSystemHelper.WriteAllText(filePath, dataTable.DataTableToFileContent());

要使用其他擴展名(如txt,我們只需將文件名更改爲dataTable.txt ”

創建Excel文件

在這裏,我們正在創建一個XLSX文件。

string filePath = @"c:\dataTable.xlsx";
DataTable dataTable = Data.Instance.DataTable;

FileSystemHelper.DeleteFileIfExists(filePath);
using (var excel = dataTable.DataTableToExcel())
{
    excel.SaveAs(new FileInfo(filePath));
}

我相信XLS也可以,只需更改擴展名並嘗試一下即可。

解決方案和項目

它是Visual Studio 2015解決方案和.NET Framework 4.5

侷限性

  • 列值將使用ToString()方法轉換爲string。因此,DateTime, decimal, float或其他seminar數據類型會話轉到string可能與預期不符。我們需要首先創建一個格式化DataTable對象。
  • 列號,順序或名稱也需要預先格式化。
  • 這可能不是創建大文件的最有效方法。

下一步是什麼?

  • 創建XMLdocpdf文件
  • ASP.NET響應示例
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章