MacでcsvからExcelファイルを生成する(その2)EPPlus編

2016.11.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

昨日、「Windowsを使わないで、CSVからExcelを生成して、一部自動化」と言う事で、NPOIを紹介させて頂きました。
MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)

しかし、Visual Studio for Mac 上から実行すると問題ないが、コマンドラインから実行すると、出力されるExcelファイルが、何故か0バイトになってしまうという問題に当たってしまいました。

本日は、比較試験も兼ねて、EPPulsで試してみました。 もちろん本日も、Visual Studio for Mac利用です。(今日はダークモード)

010

2 EPPlus

EPPlusOpen XMLの仕様に基いてExcelデータを行うライブラリですが、Excel 2007より前のバージョン(xls)には、対応していません。
EPPlus-Create advanced Excel spreadsheets on the server

005

実は、ClosedXMLも試してみたのですが、こちらは、うまく動かすことが出来ませんでした。

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'System.Drawing.KnownColors' threw an exception.
---> System.TypeInitializationException: The type initializer for 'System.Drawing.GDIPlus' threw an exception. 
---> System.DllNotFoundException: libgdiplus.dylib

3 作成手順

(1) プロジェクト作成

メニューから、ファイル > 新しいソリューションで新しいプロジェクトを作成しました。

001

名前は、ExcelGenelatorByEPPlusとしました。

002

(2) NuGetの追加

パッケージを追加しました。

003

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

007

依存関係はなく、EPPlusのみがインストールされます。

011

(3) Excelファイルの準備

出力するExcelファイルは、罫線や書式を、予め作成しています。(金額や消費税などは、式で入っています)

sample.xlsx

004

(4) csvファイルの準備

差し込みに使うデータ(品名、数量、単価)は、csv形式で用意しました。

sample.csv

サーモン,5000,150
いか,5,200
さば,2,190
まぐろ,4,230
いるか,1,12000

(5) 実装

実装は、次のようになりました。 テンプレートのExcelファイルを開いて、Csvからデータを移して、新しいExcelファイルとして保存しています。

ちょっと注意が必要なのは、SheetやCellの配列が0からではなく1から指定することです。 なお、NPOIの時のように、再計算の処理は必要ありませんでした。

using System;
using System.IO;
using System.Reflection;
using System.Linq;
using OfficeOpenXml;

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]);
            var wb = new ExcelPackage(new FileInfo(templateExcelName));
            var sheet = wb.Workbook.Worksheets.First();
            var lines = File.ReadAllLines(inputCsvName);
            foreach (var item in lines.Select((line, row) => new { line, row }))
            {
                var values = item.line.Split(',');
                foreach (int i in Enumerable.Range(0, 3))
                {
                    // データを差し込むのは7行目のカラム3個目以降(セル番号は、0からではなく1から指定)
                    var cell = sheet.Cells[item.row + 8, i + 4];
                    if (i == 0) // 品名は、文字として挿入
                    {
                        cell.Value = values[i];
                    }
                    else
                    { // 数量・単価は、数値として挿入
                        cell.Value = Int32.Parse(values[i]);
                    }
                }
                //数式の再計算は必要ありません。
                wb.SaveAs(new FileInfo(outputExcelName));
            }
        }
    }
}

4 動作確認

出力ファイルは、次のようになりました。今日も、サーモンは多い目です。

009

5 コマンドライン

Visual Studioで生成されるのは、exeファイルです。

コマンドラインから、次のように使用します。(第1パラメーター:入力CSV、第2パラメーター:出力ファイル)

$ mono ExcelGenelatorByEPPlus.exe input.csv output.xlsx

今回は、問題なくoutput.xlsxが出力されました。 もしかすると、MacでC#でExcelファイルを作るなら、EPPlus 一択かも知れません。>YOSHIEさん

6 最後に

NPOIの出力がmonoでうまく出せないのは、固有の問題のようです。XSSFWorkbookWriteメソッドで直接ファイルストリームに書き出さずに、一旦、メモリ上に吐いてから、改めてファイル化したりすると上手くいくかも知れません。(すいません、未確認です)

EPPlusを使用する場合も、グラフやマクロなどは、正常に処理できません。また、残念ながら、印刷出力も出来ません。


github [GitHub] https://github.com/furuya02/ExcelGenelatorByEPPlus

6 参考資料


EPPlusの基本的な使い方メモ (xlsx形式, Excelのインストール必要ない, COM使わない)
MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)