【忘備録】ClosedXmlのファイル操作【C#】

スポンサーリンク
homeimage 忘備録
スポンサーリンク

はじめに

ClosedXmlのファイル操作で困ったことなどを適当にまとめておきます。

Tips

ファイルオープンの方法

ファイルパスを指定して、対象ファイルを開くことができる。

xlWorkBook = new XLWorkbook(strReadPath);

ファイルオープンでエラー

前述のファイルオープンは読み書き可能で開こうとするため、他プロセスが対象ファイルを利用している場合にエラーを吐く。

以下のようにすることでファイルを読み取り専用で開くことができる。

FileStream fs = new FileStream(strReadPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
xlWorkBook = new XLWorkbook(fs);

ファイルの保存方法

名前を付けて保存する場合は、保存先のファイルパスを指定して以下のようにする。

xlWorkBook.SaveAs(strSavePath);

上書き保存は以下のコードで可能。

xlWorkBook.Save();

ファイルの保存でエラー

対象ファイルを読み取り専用で開いている場合は、上書き保存はエラーとなる。

サンプル

できる限りファイルを読み込んで、保存する際にエラー終了しないようにしたクラスを置いておきます。

using ClosedXML.Excel;
using System.IO;

namespace CSharpKnowHow.ClosedXMLSample
{
    /// <summary>
    /// エクセルファイルを管理する
    /// </summary>
    public class Excel
    {
        //Excelファイル状況
        public enum Mode : int
        {
            NG,
            RW,
            R
        };
        public Mode OpenMode { get; private set; }
        public XLWorkbook WorkBook { get; private set; }

        /// <summary>
        /// コンストラクタ
        /// プロパティの初期化
        /// </summary>
        public Excel()
        {
            //初期化
            OpenMode = Mode.NG;
            WorkBook = null;
        }

        /// <summary>
        /// Excelワークブックを開く
        /// </summary>
        /// <param name="strReadPath">ファイルパス</param>
        /// <returns>true:オープン成功/false:オープン失敗</returns>
        public bool OpenExcel(string strReadPath)
        {
            //初期化
            OpenMode = Mode.NG;
            WorkBook = null;

            //指定されたファイルが存在しない場合
            if (!File.Exists(strReadPath))
            {
                return false;
            }

            //ファイルを開く
            XLWorkbook xlWorkBook = new XLWorkbook();
            if (OpenReadWrite(strReadPath, ref xlWorkBook))
            {
                //RWモードで開いた場合
                OpenMode = Mode.RW;
            }
            else
            {
                if (OpenReadOnly(strReadPath, ref xlWorkBook))
                {
                    //Rモードで開いた場合
                    OpenMode = Mode.R;
                }
                else
                {
                    //ファイルが開けない場合
                    return false;
                }
            }

            //ファイルが開けた場合,ワークブックを保持する
            WorkBook = xlWorkBook;

            return true;
        }

        /// <summary>
        /// Excelワークブックを保存する
        /// </summary>
        /// <param name="strSavePath"></param>
        /// <returns></returns>
        public bool SaveExcel(string strSavePath = "")
        {
            //Excelワークブックの取得
            XLWorkbook xlWorkBook = WorkBook;

            //ワークブックを開いていない場合
            if (xlWorkBook == null)
            {
                return false;
            }

            //オープン状態で分岐
            if (OpenMode == Mode.R)
            {
                return strSavePath != "" && SaveAs(strSavePath, ref xlWorkBook);
            }
            else if (OpenMode == Mode.RW)
            {
                return strSavePath != "" ? SaveAs(strSavePath, ref xlWorkBook) : Save(ref xlWorkBook);
            }

            return false;
        }

        /// <summary>
        /// ExcelファイルをRWモードで開く
        /// </summary>
        /// <param name="strReadPath">ファイルパス</param>
        /// <param name="xlWorkBook">ワークブック</param>
        /// <returns>true:オープン成功/false:オープン失敗</returns>
        private bool OpenReadWrite(string strReadPath, ref XLWorkbook xlWorkBook)
        {
            //エラー回避
            try
            {
                //ExcelファイルをRWモードで開く
                xlWorkBook = new XLWorkbook(strReadPath);
            }
            catch
            {
                //RWモードで開くことができない場合
                //ex:他プロセスがExcelファイルをロック中
                //ex:Excelファイル以外を指定した場合
                return false;
            }

            //RWモードで開くことができた場合
            return true;
        }

        /// <summary>
        /// ExcelファイルをRモードで開く
        /// </summary>
        /// <param name="strReadPath">ファイルパス</param>
        /// <param name="xlWorkBook">ワークブック</param>
        /// <returns>true:オープン成功/false:オープン失敗</returns>
        private bool OpenReadOnly(string strReadPath, ref XLWorkbook xlWorkBook)
        {
            //エラー回避
            try
            {
                //読み取り専用でファイルストリームを生成
                //ファイルストリームからファイルを読み込む
                FileStream fs = new FileStream(strReadPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                xlWorkBook = new XLWorkbook(fs);
            }
            catch
            {
                //Rモードで開くことができない場合
                return false;
            }

            //Rモードで開くことができた場合
            return true;
        }

        /// <summary>
        /// Excelファイルを保存する
        /// </summary>
        /// <param name="xlWorkBook">対象ワークブック</param>
        /// <returns>true:保存成功/false:保存失敗</returns>
        private bool Save(ref XLWorkbook xlWorkBook)
        {
            //RWモード以外の場合
            if (OpenMode != Mode.RW)
            {
                return false;
            }

            //ワークブックが存在しない場合
            if (xlWorkBook == null)
            {
                return false;
            }

            //エラー回避
            try
            {
                //保存
                xlWorkBook.Save();
            }
            catch
            {
                //保存できない場合
                return false;
            }

            //保存できた場合
            return true;
        }

        /// <summary>
        /// Excelファイルを別名保存する
        /// </summary>
        /// <param name="strSavePath">保存ファイルパス</param>
        /// <param name="xlWorkBook">対象ワークブック</param>
        /// <returns>true:保存成功/false:保存失敗</returns>
        /// </summary>
        private bool SaveAs(string strSavePath, ref XLWorkbook xlWorkBook)
        {
            //RW/Rモード以外の場合
            if (OpenMode != Mode.RW && OpenMode != Mode.R)
            {
                return false;
            }

            //ワークブックが存在しない場合
            if (xlWorkBook == null)
            {
                return false;
            }

            //エラー回避
            try
            {
                //保存
                xlWorkBook.SaveAs(strSavePath);
            }
            catch
            {
                //保存できない場合
                return false;
            }

            //保存できた場合
            return true;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpKnowHow.ClosedXMLSample
{
    public class Sample
    {
        /// <summary>
        /// コンストラクタ
        /// サンプル実行
        /// </summary>
        public Sample()
        {
            string strInputPath = @"C:\Users\Ktora\sample_input.xlsm";
            string strOutputPath = @"C:\Users\Ktora\sample_output.xlsm";
            Excel excel = new Excel();
            excel.OpenExcel(strInputPath);
            excel.SaveExcel(strOutputPath);
        }
    }
}

コメント

タイトルとURLをコピーしました