CodePage | Name | DisplayName | Note |
---|---|---|---|
932 | shift_jis | Japanese (Shift-JIS) | |
20932 | EUC-JP | Japanese (JIS 0208-1990 and 0212-1990) | |
65001 | utf-8 | Unicode (UTF-8) |
上記のようなテーブルのみ含むExcelファイルをencodings.xlsxという名前でCドライブ直下に保存した場合、下記コードでDisplayNameフィールドの値の一覧を表示することができる。
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
class EncodingInfo
{
public int CodePage { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
}
class Sample
{
public static void SetProperty<T>(T obj, string name, object value)
{
PropertyInfo property = typeof(T).GetProperty(name,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
property?.SetValue(obj, Convert.ChangeType(value, property.PropertyType));
}
public static IEnumerable<T> ConvertExcelTable<T>(IXLTable table) where T : new()
{
var names = table.Fields.Select(field => field.Name).ToArray();
foreach (var row in table.DataRange.Rows())
{
var obj = new T();
foreach (var name in names)
{
SetProperty(obj, name, row.Field(name).Value);
}
yield return obj;
}
}
public static void Main(string[] args)
{
var path = @"C:\encodings.xlsx";
var workbook = new XLWorkbook(path);
var worksheet = workbook.Worksheet(1);
foreach(var encoding
in ConvertExcelTable<EncodingInfo>(worksheet.RangeUsed().AsTable()))
{
Console.WriteLine(encoding.DisplayName);
}
}
}
- Excelで数値型は
System.Double
であるため、int
型プロパティにセットしようとするとSystem.ArgumentException
例外が発生する。問題を回避するためにConvert.ChangeType
メソッドを使用しているが、また別の条件で例外が発生する可能性は十分にある。 -
IXLWorksheet.RangeUsed
メソッドは、シート内の使われている範囲のみを取得する便利なメソッド。 -
ConvertExcelTable
メソッドの戻り値であるIEnumerable<T>
の要素をすべて処理し終える前にworkbook
もしくはworksheet
を閉じると例外が発生すると思ったけれど、発生しない。具体的には、Main
メソッドの中身を以下に書き換えても問題なく動作する。
var path = @"C:\encodings.xlsx";
IEnumerable<EncodingInfo> enumerable;
using (var workbook = new XLWorkbook(path))
using (var worksheet = workbook.Worksheet(1))
{
enumerable = ConvertExcelTable<EncodingInfo>(worksheet.RangeUsed().AsTable());
}
foreach (var encoding in enumerable)
{
Console.WriteLine(encoding.DisplayName);
}