
MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
身近で、「Windowsを使わないで、CSVからExcelファイルを生成して、一部自動化」みたいな作業があったので、ちょっとやってみました。 そして、ちょうど今日、Visual Studio for Mac(preview)も公開されたので、早速使って見ました。
Visual Studio for MAC のレビューは、今、ばりばり世界中で記事になっていると思うので・・・本記事は、単に使ってみただけです。(すいません)

2 NPOI
今回、使用させて頂いたのは、Apache POIの.NETへの移植版であるNPOIです。
Windows+Excelの環境では、COMの開放に注意が必要ですが、Microsoft.Office.Interop.Excelを使用するのが、最も自由に何でも出来る選択となるでしょう。
しかし、今回は、「Windowsを使わないで・・・」という事でしたので、いくつかのPOIを試してみた結果、一番すんなり動いたNPOIになりました。
Apache POIでは、HSSFとXSSFがありますが、Excel2007(.xlsx)以降では、XSSFを使用するようです。
3 作成手順
(1) プロジェクト作成
メニューから、ファイル > 新しいソリューションで新しいプロジェクトを作成しました。

名前は、ExcelGenelatorByNpioとしました。

(2) NuGetの追加
参照を追加しました。

NuGetライブラリでは、npoiで簡単に検索できます。

依存関係から、SharpZipLibと共に、インストールされます。

(3) Excelファイルの準備
出力するExcelファイルは、罫線や書式を、予め作成しておきます。 プログラムからも作業可能ですが、定形であれば、ある程度、先に作ってしまった方が簡単かと思いました。
なお、金額や消費税などは、予め式で入ってます。
sample.xlsx

(4) csvファイルの準備
差し込みに使うデータ(品名、数量、単価)は、csv形式で用意しました。
sample.csv
サーモン,5000,150 いか,5,200 さば,2,190 まぐろ,4,230 いるか,1,12000
(5) 実装
実装は、次のようになりました。 テンプレートのExcelファイルを開いて、Csvからデータを移して、新しいExcelファイルとして保存しています。
using System;
using System.IO;
using System.Reflection;
using System.Linq;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
namespace ExcelGenelator
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            args = new String[] { "input.csv", "output.xlsx" };
            // アプリケーションのフルパス
            var appPath = Assembly.GetExecutingAssembly().Location;
            if (args.Length != 2)
            {
                Console.WriteLine($"use: mono {Path.GetFileName(appPath)} input.csv output.xlsx");
                return;
            }
            var appDirectory = Path.GetDirectoryName(appPath);
            // テンプレートExcel
            var templateExcelName = Path.Combine(appDirectory,"template.xlsx");
            if (!File.Exists(templateExcelName))
            {
                Console.WriteLine($"ERROR {templateExcelName} not Found.");
                return;
            }
            // 入力CSV
            var inputCsvName = Path.Combine(appDirectory, args[0]);
            if (!File.Exists(inputCsvName))
            {
                Console.WriteLine($"ERROR {inputCsvName} not Found.");
                return;
            }
            // 出力Excel
            var outputExcelName = Path.Combine(appDirectory, args[1]);
            using (FileStream file = new FileStream(templateExcelName, FileMode.Open, FileAccess.ReadWrite))
            {
                var wb = new XSSFWorkbook(file);
                ISheet sheet = wb.GetSheetAt(0);
                var lines = File.ReadAllLines(inputCsvName);
                foreach (var item in lines.Select((line, row) => new { line, row }))
                {
                    // データを差し込むのは7行目以降
                    var row = sheet.GetRow(item.row + 7);
                    var values = item.line.Split(',');
                    foreach (int i in Enumerable.Range(0, 3))
                    {
                        // データを差し込むカラムは3個目以降
                        var cell = row.GetCell(i + 3);
                        if (i == 0) // 品名は、文字として挿入
                        {
                            cell.SetCellValue(values[i]);
                        }
                        else
                        { // 数量・単価は、数値として挿入
                            cell.SetCellValue(Int32.Parse(values[i]));
                        }
                    }
                }
                XSSFFormulaEvaluator.EvaluateAllFormulaCells(wb); // これで、数式を再計算します
                using (var fs = new FileStream(outputExcelName, FileMode.CreateNew))
                {
                    wb.Write(fs);
                }
            }
        }
    }
}
4 動作確認
出力ファイルは、次のようになりました。ちょっとサーモンが多いです。

5 分からない・・・
Visual Studioで生成されるのは、exeファイルです。 実は、コマンドラインから、次のように使用したかったのですが・・・(第1パラメーター:入力CSV、第2パラメーター:出力ファイル)
$ mono ExcelGenelatorByNpio.exe input.csv output.xlsx
コマンドラインから実行すると、output.xlsxが0バイトになってしまいます。
Xamarin Studio でも同じでした。どなたかヒント下さい。m(.)m
2016/11/18追記
EPPlusは、出力できました。
MacでcsvからExcelファイルを生成する(その2)EPPlus編
6 最後に
今回使用した、NPOI以外にも、C#でExcelファイルを生成できるものとして次のようなものが有りました。そして、どちらも、NuGetからインストールが可能でした。


NPOIを使用する場合、Excelの機能である、グラフやマクロなどは、正常に処理できませんので注意が必要です。NPOIで処理できないセルは、無効となりますので、制約を充分確認してから作業する必要があります。また、残念ながら、印刷出力などはできません。
 [GitHub] https://github.com/furuya02/ExcelGenelatorByNpio
[GitHub] https://github.com/furuya02/ExcelGenelatorByNpio











