Quantcast
Channel: いげ太の日記
Viewing all articles
Browse latest Browse all 26

[C#] 入力データとしての Excel ファイル

$
0
0

NOTE: この記事は、当初、ココログの「いげ太のブログ」で公開していたものです。

ヤツをやっつけるにはどうすればいいだろう。それが表形式データとして整ったものであるならば、OLE DB なり ODBC なりのプロバイダ経由で、Microsoft Jet データベース エンジンに読み込み処理を丸投げしてしまえるだろう。しかし、注意書きやら補足やらタイトルやらなんやらかんやらイラナイ データまでくっついてくるのが常なのであり、そしてそれまでもプログラム側でイイ感じに処理してほしいという要求が当然のなりゆきなのであり、つまり Excel は文化。

なんか最後、結論を間違ったような気がするけど気にしない気にも留めない。こうなりゃもう CSV に変換してしまえい。とりあえずテキストで。なにはなくともテキストで。ていうか遅延バインディング書きたかっただけで。そんなノリで。

namespace Sample.LateBindingExtensions
{
using System;
using System.Reflection;

public static class Invoker
{
public static object CreateObject(string progID)
{
return Activator.CreateInstance(Type.GetTypeFromProgID(progID));
}

public static object InvokeMethod(this object self,
string name, params object[] args)
{
return self.GetType().InvokeMember(
name, BindingFlags.InvokeMethod, null, self, args);
}

public static object SetProperty(this object self,
string name, params object[] args)
{
return self.GetType().InvokeMember(
name, BindingFlags.SetProperty, null, self, args);
}

public static object GetProperty(this object self,
string name, params object[] args)
{
return self.GetType().InvokeMember(
name, BindingFlags.GetProperty, null, self, args);
}
}
}

namespace Sample
{
using System;
using System.Collections;
using System.IO;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using Sample.LateBindingExtensions;

internal enum XlFileFormat
{
xlCSV = 6,
xlCSVMac = 22,
xlCSVMSDOS = 24,
xlCSVWindows = 23,

xlTextMac = 19,
xlTextMSDOS = 21,
xlTextPrinter = 36,
xlTextWindows = 20,
xlUnicodeText = 42,
}

public class ExcelApplication
: CriticalFinalizerObject, IDisposable
{
private object xlApp;
private GCHandle excelHnd;
private Stack localScopeRcws;

private bool cellsFormatGeneral;

#region IDisposable メンバ
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion

protected virtual void Dispose(bool disposing)
{
if (this.excelHnd.IsAllocated)
{
if (this.excelHnd.Target != null)
{
this.xlApp.InvokeMethod("Quit");
Marshal.ReleaseComObject(this.xlApp);
if (disposing)
this.excelHnd.Target = null;
}
this.excelHnd.Free();
}
}

public ExcelApplication()
{
this.xlApp = Invoker.CreateObject("Excel.Application");
this.excelHnd = GCHandle.Alloc(xlApp);
this.xlApp.SetProperty("DisplayAlerts", false);
this.xlApp.SetProperty("ScreenUpdating", false);

this.localScopeRcws = new Stack();
this.cellsFormatGeneral = false;
}

~ExcelApplication()
{
this.Dispose(false);
}

public bool CellsFormatGeneral
{
get { return cellsFormatGeneral; }
set { cellsFormatGeneral = value; }
}

private object NewRcw(object rcw)
{
this.localScopeRcws.Push(rcw);
return rcw;
}

private void ReleaseRcws()
{
foreach (object rcw in this.localScopeRcws)
{
try
{
//if (rcw != null && Marshal.IsComObject(rcw))
// for (var i = 1; i > 0; )
// i = Marshal.ReleaseComObject(rcw);
if (rcw != null && Marshal.IsComObject(rcw))
Marshal.ReleaseComObject(rcw);
}
catch { }
}
this.localScopeRcws = new Stack();
}

private void WorksheetToCsv(
string bookPath, object sheetID, string csvPath)
{
var xlBook = default(object);
try
{
var xlBooks = NewRcw(this.xlApp.GetProperty("WorkBooks"));
xlBook = NewRcw(xlBooks.GetProperty(
"Open", bookPath, Type.Missing, true));
var xlSheets = NewRcw(xlBook.GetProperty("Worksheets"));
var xlSheet = NewRcw(xlSheets.GetProperty("Item", sheetID));
if (this.cellsFormatGeneral)
{
var xlCells = NewRcw(xlSheet.GetProperty("Cells"));
xlCells.SetProperty("NumberFormatLocal", "G/標準");
}
xlSheet.InvokeMethod("SaveAs", csvPath, XlFileFormat.xlCSV);
}
finally
{
if (xlBook != null)
xlBook.InvokeMethod("Close");
this.ReleaseRcws();
}
}

public void WorksheetToCsv(string bookPath)
{
var csvPath = Path.Combine(
Path.GetDirectoryName(bookPath),
Path.GetFileNameWithoutExtension(bookPath) + ".csv");
this.WorksheetToCsv(bookPath, csvPath);
}

public void WorksheetToCsv(string bookPath, string csvPath)
{
this.WorksheetToCsv(bookPath, 1, csvPath);
}

public void WorksheetToCsv(
string bookPath, int sheetIndex, string csvPath)
{
this.WorksheetToCsv(bookPath, (object)sheetIndex, csvPath);
}

public void WorksheetToCsv(
string bookPath, string sheetName, string csvPath)
{
this.WorksheetToCsv(bookPath, (object)sheetName, csvPath);
}
}
}

さあ使おう、いま使おう。

namespace Sample
{
using System;

class Program
{
static void Main(string[] args)
{
Console.Write("Excel file: ");
var book = Console.ReadLine();

using (var xlApp = new ExcelApplication())
{
xlApp.CellsFormatGeneral = true;
xlApp.WorksheetToCsv(book);
}

Console.Write("Press any key to exit.");
Console.ReadKey();
}
}
}

[セルの書式設定] をすべて [標準] にしてしまう、というのが今日のハイライト。

関連記事


Viewing all articles
Browse latest Browse all 26

Trending Articles