This site uses cookies to deliver our services. By using this site, you acknowledge that you have read and understand our Cookie and Privacy policy. Your use of Kontext website is subject to this policy. Allow Cookies and Dismiss

C#操作Excel的类以及其使用举例说明

2165 views 1 comments last modified about 9 years ago Raymond Tang

1前言
这两天由于某种需要,研究了一下.NET中对Excel的互操作,之前主要是直接通过第三方的组件等方式来操作的Excel,这次仔细的研究了一下,对常用的Excel操作需求做了一个简单的总结,比如创建Excel,设置单元格样式,合并单元格,导入内存中的DataTable,插入图片、图表等。在此基础上借助于Microsoft.Office.Interop.Excel对这些操作进行了封装最终形成了ExcelHandler类。本文主要对自己封装的这个类进行简单的举例说明,关于此类的完整代码参见第三部分。
注意:对于命名空间Microsoft.Office.Interop.Excel,使用之前需要引用COM:Microsoft Office 11.0 Object Library(office 2003 )或者Microsoft Office 12.0 Object Library(office 2007 ),如果引用列表中没有,需要自行添加 X:Program Files/Microsoft Office/OFFICE[11|12]/EXCEL.EXE的引用。如果已经安装VSTO(Visual Studio Tools For Office),亦可直接添加对X:\Program Files\Microsoft Visual Studio [9.0|8.0]\Visual Studio Tools for Office\PIA\Office[11|12]\Microsoft.Office.Interop.Excel.dll的引用。

2ExcelHandler类举例说明
为了展示该类的使用方法,新建了一个WinForm的测试项目进行测试,项目名称可自定,添加对ExcelHandler的dll的引用。所有测试代码均放在窗体的一个按钮单击事件的处理方法中。

2.1创建Excel文件

 /// <summary>
/// 测试ExcelHandler类
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonTest_Click(object sender, EventArgs e)
{
string excelFilePath = string.Format("{0}Excel-{1}.xls", AppDomain.CurrentDomain.BaseDirectory, DateTime.Now.ToString("yyyyMMddHHmmss"));

using (ExcelHandler handler = new ExcelHandler(excelFilePath, true))
{
handler.OpenOrCreate();
MessageBox.Show("创建Excel成功!");
handler.Save();
MessageBox.Show(string.Format("保存Excel成功!Excel路径:{0}", excelFilePath));

}

点击按钮执行后,可以看到在Debug目录下多了一个Excel文件

此文件的完整路径为:F:\My Projects\Tanging.DataVisualization\Tanging.DataVisualization\bin\Debug\Excel-20100314181502.xls。
注意:之后的例子的Excel的文件的路径需要为你自己创建的Excel的相应路径。
下面将举例说明对此Excel文件进行操作。

2.2创建自己的工作表Worksheet
 private void buttonTest_Click(object sender, EventArgs e)
{
string excelFilePath = string.Format("{0}Excel-20100314181502.xls", AppDomain.CurrentDomain.BaseDirectory);

using (ExcelHandler handler = new ExcelHandler(excelFilePath, false))//设置第二个参数为false表示直接打开现有的Excel文档
{
handler.OpenOrCreate();
//创建一个Worksheet
Worksheet sheet = handler.AddWorksheet("TestSheet");
//删除除TestSheet之外的其余Worksheet
handler.DeleteWorksheetExcept(sheet);
handler.Save();
}
}
再次打开创建的Excel,可以看到新建的Worksheet

2.3单元格、Range等的操作

下面设置A1到E5的单元格样式,并且设置单元格值等
private void buttonTest_Click(object sender, EventArgs e)
{
string excelFilePath = string.Format("{0}Excel-20100314181502.xls", AppDomain.CurrentDomain.BaseDirectory);

using (ExcelHandler handler = new ExcelHandler(excelFilePath, false))//设置第二个参数为false表示直接打开现有的Excel文档
{
handler.OpenOrCreate();
//获得Worksheet对象
Worksheet sheet = handler.GetWorksheet("TestSheet");
//A1-E5
Range range = handler.GetRange(sheet, 1, 1, 5, 5);
handler.SetRangeFormat(range);

handler.SetCellValue(sheet, 1, 1, "测试");
handler.SetCellValue(sheet, 2, 1, "测试2");

range.Font.Bold = true;//加粗

handler.Save();
}
}
效果如下:

2.4导入DataTable
代码如下:
private void buttonTest_Click(object sender, EventArgs e)
{
string excelFilePath = string.Format("{0}Excel-20100314181502.xls", AppDomain.CurrentDomain.BaseDirectory);

using (ExcelHandler handler = new ExcelHandler(excelFilePath, false))//设置第二个参数为false表示直接打开现有的Excel文档
{
handler.OpenOrCreate();
//获得Worksheet对象
Worksheet sheet = handler.GetWorksheet("TestSheet");
//A1-E5
Range range = handler.GetRange(sheet, 1, 1, 5, 5);
handler.SetRangeFormat(range);
range.Font.Bold = true;

System.Data.DataTable table = new System.Data.DataTable();
table.Columns.AddRange(new DataColumn[] { new DataColumn("测试列1"), new DataColumn("测试列2"), new DataColumn("测试列3") });
Random random = new Random(20);
for (int i = 0; i < 10; i++)
{
table.Rows.Add(random.Next(10000), random.Next(10000), random.Next(10000));
}

//从第6行第一列导入数据
handler.ImportDataTable(sheet, "测试导入表格", true, new string[] { "测试列1", "测试列2", "测试列3" }, 6, 1, table);

handler.Save();
}
}

结果如下图:

2.5 插入图片
下面插入一张图片到Excel的第一行第五列,代码如下:
private void buttonTest_Click(object sender, EventArgs e)
{
string excelFilePath = string.Format("{0}Excel-20100314181502.xls", AppDomain.CurrentDomain.BaseDirectory);

using (ExcelHandler handler = new ExcelHandler(excelFilePath, false))//设置第二个参数为false表示直接打开现有的Excel文档
{
handler.OpenOrCreate();
//获得Worksheet对象
Worksheet sheet = handler.GetWorksheet("TestSheet");

//图片地址
string filePath = string.Format("{0}test.png", AppDomain.CurrentDomain.BaseDirectory);

//从第1行第5列插入图片
Picture pic = handler.AddImage(sheet, filePath, 1, 5);


handler.Save();
}
}
效果如下图:
3ExcelHandler 类完整源码
/* ***********************************************
* Author:          Raymond Tang
* Email:           china.raymond@hotmail.com
* Blog:               http://blog.tanging.net
* Created Time:    2010-3-14 9:59:43
* Class:           Tanging.Interop.Excel.ExcelHandler
* ***********************************************/

using System;
using System.IO;
using System.Reflection;
using System.Text;
using Xls = Microsoft.Office.Interop.Excel;
using System.Data;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Tanging.Interop.Excel
{
/// <summary>
/// Excel处理类
/// </summary>
/// <remarks>可以用于创建Excel,操作工作表,设置单元格样式对齐方式等,导入内存、数据库中的数据表,插入图片到Excel等</remarks>
public sealed class ExcelHandler : IDisposable
{
#region [构造函数]

/// <summary>
/// ExcelHandler的构造函数
/// </summary>
/// <param name="fileName">Excel文件名,绝对路径</param>
public ExcelHandler(string fileName)
: this(fileName, false)
{

}

/// <summary>
/// 创建ExcelHandler对象,指定文件名以及是否创建新的Excel文件
/// </summary>
/// <param name="fileName">Excel文件名,绝对路径</param>
/// <param name="createNew">是否创建新的Excel文件</param>
public ExcelHandler(string fileName, bool createNew)
{
this.FileName = fileName;
this.mCreateNew = createNew;
}

#endregion

#region [字段和属性]

private static readonly object missing = Missing.Value;

private string mFileName;
/// <summary>
/// Excel文件名
/// </summary>
public string FileName
{
get { return mFileName; }
set { mFileName = value; }
}
/// <summary>
/// 是否新建Excel文件
/// </summary>
private bool mCreateNew;

private Xls.Application mApp;
/// <summary>
/// 当前Excel应用程序
/// </summary>
public Xls.Application App
{
get { return mApp; }
set { mApp = value; }
}

private Xls.Workbooks mAllWorkbooks;
/// <summary>
/// 当前Excel应用程序所打开的所有Excel工作簿
/// </summary>
public Xls.Workbooks AllWorkbooks
{
get { return mAllWorkbooks; }
set { mAllWorkbooks = value; }
}

private Xls.Workbook mCurrentWorkbook;
/// <summary>
/// 当前Excel工作簿
/// </summary>
public Xls.Workbook CurrentWorkbook
{
get { return mCurrentWorkbook; }
set { mCurrentWorkbook = value; }
}

private Xls.Worksheets mAllWorksheets;
/// <summary>
/// 当前Excel工作簿内的所有Sheet
/// </summary>
public Xls.Worksheets AllWorksheets
{
get { return mAllWorksheets; }
set { mAllWorksheets = value; }
}

private Xls.Worksheet mCurrentWorksheet;
/// <summary>
/// 当前Excel中激活的Sheet
/// </summary>
public Xls.Worksheet CurrentWorksheet
{
get { return mCurrentWorksheet; }
set { mCurrentWorksheet = value; }
}

#endregion

#region [初始化操作,打开或者创建文件]
/// <summary>
/// 初始化,如果不创建新文件直接打开,否则创建新文件
/// </summary>
public void OpenOrCreate()
{
this.App = new Xls.ApplicationClass();
this.AllWorkbooks = this.App.Workbooks;

if (!this.mCreateNew)//直接打开
{
if (!File.Exists(this.FileName))
{
throw new FileNotFoundException("找不到指定的Excel文件,请检查路径是否正确!", this.FileName);
}

this.CurrentWorkbook = this.AllWorkbooks.Open(this.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Xls.XlPlatform.xlWindows, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

}
else//创建新文件
{
if (File.Exists(this.FileName))
{
File.Delete(this.FileName);
}
this.CurrentWorkbook = this.AllWorkbooks.Add(Type.Missing);

}

this.AllWorksheets = this.CurrentWorkbook.Worksheets as Xls.Worksheets;
this.CurrentWorksheet = this.CurrentWorkbook.ActiveSheet as Xls.Worksheet;
this.App.DisplayAlerts = false;
this.App.Visible = false;
}
#endregion

#region [Excel Sheet相关操作等]

/// <summary>
/// 根据工作表名获取Excel工作表对象的引用
/// </summary>
/// <param name="sheetName"></param>
/// <returns></returns>
public Xls.Worksheet GetWorksheet(string sheetName)
{
return this.CurrentWorkbook.Sheets[sheetName] as Xls.Worksheet;
}

/// <summary>
/// 根据工作表索引获取Excel工作表对象的引用
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Xls.Worksheet GetWorksheet(int index)
{
return this.CurrentWorkbook.Sheets.get_Item(index) as Xls.Worksheet;
}

/// <summary>
/// 给当前工作簿添加工作表并返回的方法重载,添加工作表后不使其激活
/// </summary>
/// <param name="sheetName"></param>
/// <returns></returns>
public Xls.Worksheet AddWorksheet(string sheetName)
{
return this.AddWorksheet(sheetName, false);
}

/// <summary>
/// 给当前工作簿添加工作表并返回
/// </summary>
/// <param name="sheetName">工作表名</param>
/// <param name="activated">创建后是否使其激活</param>
/// <returns></returns>
public Xls.Worksheet AddWorksheet(string sheetName, bool activated)
{
Xls.Worksheet sheet = this.CurrentWorkbook.Worksheets.Add(Type.Missing, Type.Missing, 1, Type.Missing) as Xls.Worksheet;
sheet.Name = sheetName;
if (activated)
{
sheet.Activate();
}
return sheet;
}

/// <summary>
/// 重命名工作表
/// </summary>
/// <param name="sheet">工作表对象</param>
/// <param name="newName">工作表新名称</param>
/// <returns></returns>
public Xls.Worksheet RenameWorksheet(Xls.Worksheet sheet, string newName)
{
sheet.Name = newName;
return sheet;
}

/// <summary>
/// 重命名工作表
/// </summary>
/// <param name="oldName">原名称</param>
/// <param name="newName">新名称</param>
/// <returns></returns>
public Xls.Worksheet RenameWorksheet(string oldName, string newName)
{
Xls.Worksheet sheet = this.GetWorksheet(oldName);
return this.RenameWorksheet(sheet, newName);
}

/// <summary>
/// 删除工作表
/// </summary>
/// <param name="sheetName">工作表名</param>
public void DeleteWorksheet(string sheetName)
{
if (this.CurrentWorkbook.Worksheets.Count <= 1)
{
throw new InvalidOperationException("工作簿至少需要一个可视化的工作表!");
}
this.GetWorksheet(sheetName).Delete();
}

/// <summary>
/// 删除除参数sheet指定外的其余工作表
/// </summary>
/// <param name="sheet"></param>
public void DeleteWorksheetExcept(Xls.Worksheet sheet)
{
foreach (Xls.Worksheet ws in this.CurrentWorkbook.Worksheets)
{
if (sheet != ws)
{
ws.Delete();
}
}
}


#endregion

#region [单元格,Range相关操作]

/// <summary>
/// 设置单元格的值
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="rowNumber">单元格行号</param>
/// <param name="columnNumber">单元格列号</param>
/// <param name="value">单元格值</param>
public void SetCellValue(Xls.Worksheet sheet, int rowNumber, int columnNumber, object value)
{
sheet.Cells[rowNumber, columnNumber] = value;
}

/// <summary>
/// 合并单元格
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="rowNumber1">第一个单元格行号</param>
/// <param name="columnNumber1">第一个单元格列号</param>
/// <param name="rowNumber2">结束单元格行号</param>
/// <param name="columnNumber2">结束单元格列号</param>
public void MergeCells(Xls.Worksheet sheet, int rowNumber1, int columnNumber1, int rowNumber2, int columnNumber2)
{
Xls.Range range = this.GetRange(sheet, rowNumber1, columnNumber1, rowNumber2, columnNumber2);
range.Merge(Type.Missing);
}

/// <summary>
/// 获取Range对象
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="rowNumber1">第一个单元格行号</param>
/// <param name="columnNumber1">第一个单元格列号</param>
/// <param name="rowNumber2">结束单元格行号</param>
/// <param name="columnNumber2">结束单元格列号</param>
/// <returns></returns>
public Xls.Range GetRange(Xls.Worksheet sheet, int rowNumber1, int columnNumber1, int rowNumber2, int columnNumber2)
{
return sheet.get_Range(sheet.Cells[rowNumber1, columnNumber1], sheet.Cells[rowNumber2, columnNumber2]);
}
#endregion

#region [设置单元格、Range的样式、对齐方式自动换行等]

/// <summary>
/// 自动调整,设置自动换行以及自动调整列宽
/// </summary>
/// <param name="range"></param>
public void AutoAdjustment(Xls.Range range)
{
range.WrapText = true;
range.AutoFit();
}

/// <summary>
/// 设置Range的单元格样式
/// </summary>
/// <remarks>将各项值设置为默认值</remarks>
/// <param name="range"></param>
public void SetRangeFormat(Xls.Range range)
{
this.SetRangeFormat(range, 11, Xls.Constants.xlAutomatic, Xls.Constants.xlColor1, Xls.Constants.xlLeft);
}

/// <summary>
/// 设置Range的单元格样式
/// </summary>
/// <remarks>将各项值设置为默认值</remarks>
/// <param name="sheet"></param>
/// <param name="rowNumber1"></param>
/// <param name="columnNumber1"></param>
/// <param name="rowNumber2"></param>
/// <param name="columNumber2"></param>
public void SetRangeFormat(Xls.Worksheet sheet, int rowNumber1, int columnNumber1, int rowNumber2, int columNumber2)
{
this.SetRangeFormat(sheet, rowNumber1, columnNumber1, rowNumber2, columNumber2, 11, Xls.Constants.xlAutomatic);
}

/// <summary>
/// 设置Range的单元格样式
/// </summary>
/// <param name="sheet"></param>
/// <param name="rowNumber1">第一个单元格行号</param>
/// <param name="columnNumber1">第一个单元格列号</param>
/// <param name="rowNumber2">结束单元格行号</param>
/// <param name="columnNumber2">结束单元格列号</param>
/// <param name="fontSize"></param>
/// <param name="fontName"></param>
public void SetRangeFormat(Xls.Worksheet sheet, int rowNumber1, int columnNumber1, int rowNumber2, int columNumber2, object fontSize, object fontName)
{
this.SetRangeFormat(this.GetRange(sheet, rowNumber1, columnNumber1, rowNumber2, columNumber2), fontSize, fontName, Xls.Constants.xlColor1, Xls.Constants.xlLeft);
}

/// <summary>
/// 设置Range的单元格样式
/// </summary>
/// <param name="range">Range对象</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontName">字体名称</param>
/// <param name="color">字体颜色</param>
/// <param name="horizontalAlignment">水平对齐方式</param>
public void SetRangeFormat(Xls.Range range, object fontSize, object fontName, Xls.Constants color, Xls.Constants horizontalAlignment)
{
range.Font.Color = color;
range.Font.Size = fontSize;
range.Font.Name = fontName;
range.HorizontalAlignment = horizontalAlignment;
}




#endregion

#region [导入内存中的DataTable]


/// <summary>
/// 导入内存中的数据表到Excel中
/// </summary>
/// <remarks>直接导入到工作表的最起始部分</remarks>
/// <param name="sheet"></param>
/// <param name="headerTitle"></param>
/// <param name="showTitle"></param>
/// <param name="headers"></param>
/// <param name="table"></param>
public void ImportDataTable(Xls.Worksheet sheet, string headerTitle, bool showTitle, object[] headers, DataTable table)
{
this.ImportDataTable(sheet, headerTitle, showTitle, headers, 1, 1, table);
}

/// <summary>
/// 导入内存中的数据表到Excel中
/// </summary>
/// <remarks>直接导入到工作表的最起始部分,且不显示标题行</remarks>
/// <param name="sheet"></param>
/// <param name="headers"></param>
/// <param name="table"></param>
public void ImportDataTable(Xls.Worksheet sheet, object[] headers, DataTable table)
{
this.ImportDataTable(sheet, null, false, headers, table);

}

/// <summary>
/// 导入内存中的数据表到Excel中
/// </summary>
/// <remarks>标题行每一列与DataTable标题一致</remarks>
/// <param name="sheet"></param>
/// <param name="table"></param>
public void ImportDataTable(Xls.Worksheet sheet, DataTable table)
{
List<string> headers = new List<string>();
foreach (DataColumn column in table.Columns)
{
headers.Add(column.Caption);
}
this.ImportDataTable(sheet, headers.ToArray(), table);
}


/// <summary>
/// 导入内存中的数据表到Excel中
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="headerTitle">表格标题</param>
/// <param name="showTitle">是否显示表格标题行</param>
/// <param name="headers">表格每一列的标题</param>
/// <param name="rowNumber">插入表格的起始行号</param>
/// <param name="columnNumber">插入表格的起始列号</param>
/// <param name="table">内存中的数据表</param>
public void ImportDataTable(Xls.Worksheet sheet, string headerTitle, bool showTitle, object[] headers, int rowNumber, int columnNumber, DataTable table)
{
int columns = table.Columns.Count;
int rows = table.Rows.Count;

int titleRowIndex = rowNumber;
int headerRowIndex = rowNumber;
Xls.Range titleRange = null;

if (showTitle)
{
headerRowIndex++;
//添加标题行,并设置样式
titleRange = this.GetRange(sheet, rowNumber, columnNumber, rowNumber, columnNumber + columns - 1);
titleRange.Merge(missing);

this.SetRangeFormat(titleRange, 16, Xls.Constants.xlAutomatic, Xls.Constants.xlColor1, Xls.Constants.xlCenter);
titleRange.Value2 = headerTitle;
}

//添加表头
int m = 0;
foreach (object header in headers)
{
this.SetCellValue(sheet, headerRowIndex, columnNumber + m, header);
m++;
}

//添加每一行的数据
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
sheet.Cells[headerRowIndex + i + 1, j + columnNumber] = table.Rows[i][j];
}
}

}

#endregion

#region [插入图片到Excel中的相关方法]
/// <summary>
/// 插入图片
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="imageFilePath">图片的绝对路径</param>
/// <param name="rowNumber">单元格行号</param>
/// <param name="columnNumber">单元格列号</param>
/// <returns></returns>
public Xls.Picture AddImage(Xls.Worksheet sheet, string imageFilePath, int rowNumber, int columnNumber)
{
Xls.Range range = this.GetRange(sheet, rowNumber, columnNumber, rowNumber, columnNumber);
range.Select();
Xls.Pictures pics = sheet.Pictures(missing) as Xls.Pictures;
Xls.Picture pic = pics.Insert(imageFilePath, missing);
pic.Left = (double)range.Left;
pic.Top = (double)range.Top;
return pic;
}

/// <summary>
/// 插入图片
/// </summary>
/// <param name="sheet">工作表</param>
/// <param name="imageFilePath">图片的绝对路径</param>
/// <param name="rowNumber">单元格行号</param>
/// <param name="columnNumber">单元格列号</param>
/// <param name="width">图片的宽度</param>
/// <param name="height">图片的高度</param>
/// <returns></returns>
public Xls.Picture AddImage(Xls.Worksheet sheet, string imageFilePath, int rowNumber, int columnNumber, double width, double height)
{
Xls.Picture pic = this.AddImage(sheet, imageFilePath, rowNumber, columnNumber);
pic.Width = width;
pic.Height = height;
return pic;
}

///// <summary>
///// 插入图片
///// </summary>
///// <remarks>从流中读取图片</remarks>
///// <param name="sheet"></param>
///// <param name="imageStream"></param>
///// <param name="x"></param>
///// <param name="y"></param>
///// <param name="width"></param>
///// <param name="height"></param>
///// <returns></returns>
//public Xls.Picture AddImage(Xls.Worksheet sheet, Stream imageStream, int x, int y, double width, double height)
//{

//}

#endregion

#region [保存Excel]

/// <summary>
/// 保存Excel
/// </summary>
public void Save()
{
if (this.mCreateNew)
{
this.SaveAs(this.FileName);
}
else
{
this.CurrentWorkbook.Save();
}

//this.SaveAs(this.FileName);
}

/// <summary>
/// 保存Excel
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public void SaveAs(string filePath)
{
this.CurrentWorkbook.SaveAs(filePath, Xls.XlFileFormat.xlWorkbookNormal, missing, missing, missing,
missing, Xls.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
}

#endregion


#region [公共帮助方法]
/// <summary>
/// 更新Uri
/// </summary>
public string UpdateUri
{
get
{
return "http://hi.baidu.com/1987raymond";
}
}

#endregion

#region [IDisposable 成员]
/// <summary>
/// 对象销毁时执行的操作
/// </summary>
public void Dispose()
{

//this.CurrentWorkbook.Close(true, this.FileName, missing);
Marshal.FinalReleaseComObject(this.CurrentWorkbook);
this.CurrentWorkbook = null;

this.App.Quit();
Marshal.FinalReleaseComObject(this.App);
this.App = null;

System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}

#endregion
}
}


Related pages

Set AttachDbFilename as Relative Path in .NET Core

148 views   0 comments last modified about 3 months ago

.NET Framework, you can use |DataDirectory| to configure connection string when connecting to SQL Server database file via attach mode: AttachDbFilename=|DataDirectory|\dbname.mdf In .NET Core, you cannot directly set SQL Server Express connec...

View detail

Instantiate a Service in ConfigureServices Method in .NET Core

31 views   0 comments last modified about 3 months ago

.NET Core is built in with dependency injection. Usually method ConfigureServices in Startup class is used to register services in the container. The signature of the method looks like the following: public void ConfigureServices(IServiceC...

View detail

ASP.NET Core 2.1 Error - 'Cyrillic' is not a supported encoding name

143 views   0 comments last modified about 3 months ago

After upgrading to ASP.NET Core 2.1 (.NET Core SDK 2.1.301), you may encounter the following error about encoding: System.ArgumentException &nbsp;&nbsp; HResult=0x80070057 &nbsp;&nbsp; Message='Cyrillic' is not a supported encoding name. For information on defining a custo...

View detail

SQLite in .NET Core with Entity Framework Core

86 views   0 comments last modified about 3 months ago

SQLite is a self-contained and embedded SQL database engine. In .NET Core, Entity Framework Core provides APIs to work with SQLite. This page provides sample code to create a SQLite database using package Microsoft.EntityFrameworkCore.Sqlite . Create sample project ...

View detail

Tuples in C# (4.x, 7.0, 7.1)

161 views   0 comments last modified about 7 months ago

What is a tuple? Tuple is an ordered sequence, fixed-size, immutable and of heterogeneous objects. Tuple has been existing in other languages such as F#, Python, Perl and etc. for a long time. It was first introduced into C# from C# 4.0 and has been evolving over time. Since C# 7.1, tuple...

View detail

C# version history and core features

129 views   0 comments last modified about 8 months ago

C# is my favourite programming language and has been evolving overtime. I have been programming with many other languages but C# is always my favourite because it is simple and easy to use. Visual Studio is the most powerful tool I’ve ever used. To me, programming efficiency and peformance are th...

View detail

Add comment

Please login first to add comments.  Log in New user?  Register

Comments (1)

Q Re:C#操作Excel的类以及其使用举例说明

*** about 4 years ago

QQ