4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

簡易Excel Viewer(ReoGridコンポーネント使用)の作成 CSVファイル読み込み編

Last updated at Posted at 2022-08-04

はじめに

前記事にてCSVファイルの読み込みをした場合、Excel同様に前0が消えてしまったという段階でした。

残念ながら北海道の都道府県コード"01"が、Excel同様に前0が消えてしまう。
image.png

コメントも頂いたのですが、文字列書式を設定してからCSVファイルの読み込みをすれば前0が消えなくなるのではと思って試したのですが、Loadメソッドを実行するとワークシートを新規作成するようになっているため、予め文字列書式を設定しても意味がなかったです。

どうにか出来ないか?

ReoGridコンポーネントはExcelに近い見た目と操作感があるので、前0が消えないようになればCSVエディタとしての使い道が広がる。

ソースコードがGitHubに公開されているので、何をしているかが分かります。

Loadメソッドを呼ぶとワークシートを新規作成してしまうので、Loadメソッドを使わずにワークシートに文字列書式を設定してからCSVファイルの読み込みだけするReadメソッドを呼べばいいわけです。

リフレクションで呼ぶ

Readメソッドは、internal static class CSVFormatに定義されています。
internalは「アセンブリが同じクラスのみから参照できる」というアクセス修飾子です。

CSVFormat.cs
internal static class CSVFormat
{
     public static void Read(Stream stream, Worksheet sheet, RangePosition targetRange, 
			Encoding encoding = null, int bufferLines = DEFAULT_READ_BUFFER_LINES, bool autoSpread = true)

この場合、通常の呼び出しでは使えないですがリフレクションを使用することで呼び出すことができます。
列Aだけ文字列書式にしてから、Readメソッドを使ってCSVファイルを読んでみます。

private void button1_Click(object sender, EventArgs e)
{
    string path = "c03.csv";

    Worksheet sheet = grid.CurrentWorksheet;
    sheet.SetRangeDataFormat("A:A", CellDataFormatFlag.Text);

    RangePosition targetRange = RangePosition.EntireRange;

    Assembly asm = Assembly.LoadFrom("unvell.ReoGrid.dll");
    Module mod = asm.GetModule("unvell.ReoGrid.dll");
    System.Type type = mod.GetType("unvell.ReoGrid.IO.CSVFormat");
    if (type != null)
    {
        using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            MethodInfo readMethod = type.GetMethod("Read");
            object ret = readMethod.Invoke(null, new object[] { fs, sheet, targetRange, Encoding.Default, 512, true });
        }
    }
}

スクリーンショット 2022-08-05 1.48.42.png

TSVファイルの読み込み

ReoGridコンポーネントでは、Excel(xlsx)、RGF(ReoGrid Format)、CSV(カンマ区切り)ファイルしか対応していません。
よって、タブ区切りのTSVファイルを読む込みしたい場合、もう一工夫する必要があります。

CSV(カンマ区切り)ファイルに限定されているのは、正規表現でカンマ区切りで固定されているからです。

CSVFormat.cs
private static Regex lineRegex = new Regex("\\s*(\\\"(?<item>[^\\\"]*)\\\"|(?<item>[^,]*))\\s*,?", RegexOptions.Compiled);

これをタブ区切りにするには、リフレクションを使ってタブ用の正規表現に書き換えればいいわけです。

Regex lineRegex = new Regex("\\s*(\\\"(?<item>[^\\\"]*)\\\"|(?<item>[^\\t]*))\\s*\\t?", RegexOptions.Compiled);

var fiedlineRegex = type.GetField("lineRegex", BindingFlags.Static | BindingFlags.NonPublic);
fiedlineRegex.SetValue(null, lineRegex);

テスト用のCSVファイルをタブ区切りのTSVファイルして、読み込んだところ表示することができました。

この仕組みを使えば指定した文字列区切りで読むことが可能になります。
また正規表現で桁区切りにすれば、固定帳ファイルも読めるようになるはずです。

最後に

全列を文字列書式にしてしまうのもあるのですが、Schema.iniファイルのような定義ファイルを用意してCSVファイルを読むようにすればいい。文字列書式でもコードなら左寄せではなくて中央表示にしたりも出来ますし、数値も3桁区切り表示とかも出来ます。

作り込めばいろいろ出来そうです。夏休みも近いので挑戦してみようかな。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?