目錄
背景
導出的文件類型是什麼?
- 帶分隔符的純文本文件(擴展名爲.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對象。
- 列號,順序或名稱也需要預先格式化。
- 這可能不是創建大文件的最有效方法。
下一步是什麼?
- 創建XML,doc和pdf文件
- ASP.NET響應示例