簡易Excel Viewer(ReoGridコンポーネント使用)の作成

# はじめに
ローカルネットワーク環境で自社アプリケーションからExcelファイル(.xls)を出力したものの、Excelがインストールされていないので内容を確認するには、ExcelインストールされているPCにファイルを持っていかなければならない。
「Microsoft Excel Viewer」があったなとダウンロードしようとしたら、既に2018年4月に廃止されていました。
オープンソースの「OpenOffice」や「LibreOffice」をインストールすれば参照できるけど、そこまで求めていない。個人PCだったら「Google スプレッドシート」でブラウザ上からExcelファイル(.xls)の内容を参照することが出来るけどね。

# ReoGridの紹介
ReoGridは、Microsoftの表計算ソフト「Excel」の特徴と機能を数多く備えたマルチプラットフォーム対応の表計算スプレッドシート開発ツールです。ReoGridは Excel に依存せず、.NETアプリケーションの中に組み込んで動作します。

https://reogrid.net/jp/

ソースコードの配布ライセンス：MIT Licenseとなっています。

https://github.com/unvell/ReoGrid

## xlsからxlsxファイルのコンバート
ReoGridはExcel(2007バージョン以降）ファイル形式の読み込みには対応していますが、Excel 97-2004 (.xls) のファイル形式には対応していません。
そこは、「FreeSpire.xls」を使用することにします。これは中国[E-iceblue](https://www.e-iceblue.com/)が提供するofficeの.NETコンポーネントの1つで無償版のものです。
無償版制限としては、Excelファイルの編集は、ブックごとに5シート、1シートあたり200行に制限されています。
今回はxlsからxlsxファイルのコンバートでのみ使用するので、無償版制限は引っ掛からないかも知れません。

# サンプル
サンプルとして第2章 日本食品標準成分表 Exceｌ(日本語版)の「1.穀類」のExcelを表示させてみます。

https://www.mext.go.jp/a_menu/syokuhinseibun/1365420.htm

Mac上のExcel 2019で表示したもの
![スクリーンショット 2022-07-24 14.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/16545695-fbac-5845-9ead-0aefa3ee0e63.png)

# WPF実装
最近、WPFを使用していたのでNuGetで`unvell.ReoGridWPF.dll`と`FreeSpire.XLS`をインストールします。
また、Excelファイルを開くためにメインメニューにファイル->開くのみ用意します。

## ソースコード
```xml:MainWindow.xaml
<Window x:Class="ExcelViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ExcelViewer"
        xmlns:rg="clr-namespace:unvell.ReoGrid;assembly=unvell.ReoGrid"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="ファイル">
                    <MenuItem Header="開く" Click="MenuItem_Click"/>
                </MenuItem>
           </Menu>
            <rg:ReoGridControl x:Name = "grid" />
        </DockPanel>
</Window>
```

```cs:MainWindow.cs
using Microsoft.Win32;
using Spire.Xls;
using System;
using System.IO;
using System.Windows;
using unvell.ReoGrid;

namespace ExcelViewer
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.DefaultExt = ".xlsx";
            dlg.Filter = "Supported file format(*.xlsx;*.xls;*.csv)|*.xlsx;*.xls|Excel 2007 Document(*.xlsx)|*.xlsx|Excel 97-2003 Document(*.xls)|*.xls|CSV(*.csv)|*.csv";

            if (dlg.ShowDialog() == true)
            {
                string path = dlg.FileName;

                // Open document 
                try
                {
                    if (Path.GetExtension(path) == ".xls")
                    {
                        // xlsをxlsxに変換して保存
                        Workbook workbook = new Workbook();
                        workbook.LoadFromFile(path);
                        path = Path.GetFileNameWithoutExtension(dlg.FileName) + ".xlsx";
                        workbook.SaveToFile(path, ExcelVersion.Version2007);
                    }

                    grid.Load(path);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Loading error: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
        }
    }
}
```

## 結果
2行目と4行目の表示が見切れてしまっています。
6行目の文字列が重なって表示されてしまっています。
エラーが原因なのか、167行あるはずが30行目で終わってしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/beb7faf7-b8a0-dcab-fc18-b2f386cc169a.png)

### 例外エラー
ロード時に下記の例外エラーが出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/3f7492bc-d75c-bce7-bef4-b7a9091ab01b.png)

例外メッセージの詳細としてフォントが足りない感じ、WPF版で発生するがWinForm版ではエラーにはならない。
```
MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.System.Collections.Generic.IDictionary<System.Int32,System.UInt16>.get_Item(Int32 i)
```

* https://github.com/unvell/ReoGrid/issues/149
* https://github.com/unvell/ReoGrid/issues/338

# WinForm実装
WPF版では例外エラーが発生してしまうので、WinForm版に変更する。

【2022/08/05追記】
今後のため、using Spire.Xls;を消して、using unvell.ReoGrid;にしました。

## ソースコード
```cs:frmMain.cs
using System;
using System.IO;
using System.Windows.Forms;
using unvell.ReoGrid;

namespace ExcelViewer2
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();

            grid.SheetTabWidth = 150;
        }

        private void OpenMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.DefaultExt = ".xlsx";
            dlg.Filter = "Supported file format(*.xlsx;*.xls;*.csv)|*.xlsx;*.xls|Excel 2007 Document(*.xlsx)|*.xlsx|Excel 97-2003 Document(*.xls)|*.xls|CSV(*.csv)|*.csv";

            // Process open file dialog box results 
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string path = dlg.FileName;

                // Open document 
                try
                {
                    if (Path.GetExtension(path) == ".xls")
                    {
                        // xlsをxlsxに変換して保存
                        Spire.Xls.Workbook workbook = new Spire.Xls.Workbook();
                        workbook.LoadFromFile(path);
                        path = Path.GetFileNameWithoutExtension(dlg.FileName) + ".xlsx";
                        workbook.SaveToFile(path, Spire.Xls.ExcelVersion.Version2007);
                    }

                    grid.Load(path);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Loading error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }
    }
}
```

## 結果
WPF同様に2行目と4行目の表示が見切れてしまっています。
今回は167行全て表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/159f950a-e916-11d4-675a-d0285eefd514.png)

### xlsファイルの読み込み
サンプルのExcelファイルを、Excel 97-2004 (.xls)のファイル形式に保存し直して表示してみました。
結果は、「FreeSpire.xls」のxlsからxlsxファイル形式のコンバート機能により同じように表示されることが確認できました。

### CSVファイルの読み込み
CSVファイルの読み込みも出来るので確認してみました。
残念ながら北海道の都道府県コード"01"が、Excel同様に前0が消えてしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/ab575589-4c07-9864-8f96-d3e194f10384.png)

【2022/08/05追記】
前0が消えるのを対処してみました。

https://qiita.com/yaju/items/f0e7fd81636885305211

# 最後に
単純な表データとかなら簡易的にExcelファイルの内容を確認するくらいには使用できる感じですね。
ただCSVファイルの表示が残念だな、前0が消えなければ、まだCSVエディタとしての使い道があったんだけど。