COPY コマンドで取り込む UTF8 のテキストファイルは BOM 無しなんですね
PostgreSQL で UTF8 で作ったデータベースに COPY コマンドで CSV ファイルからテーブルにデータを取り込もうとしたら、エラー発生。
ERROR: invalid input syntax for type 1列目のカラムの型: "1行1列目の値" SQLステート:22P02 コンテキスト:COPY テーブル名, line 1, column 1列目のカラム名: "1行1列目の値"
COPY コマンドのマニュアルを見ても何が悪いのか分からず、1時間経過―。
あ…COPY コマンドで取り込むテキストファイルは UTF8 だと BOM 無しなんですね…。あ…、はい…、BOM 無しで保存しましたら難なく取り込めました…。はい…、本当にありがとうございました…。
T4 Template を触ってみた
XMLファイルを Linq to XML で読み込んで、T4 Template を使ってコードを生成してみたので、メモメモ。
まずは適当にコンソールアプリプロジェクトをつくって、入力用のXMLファイル(今回は People.xml)をプロジェクトに追加します。
<?xml version="1.0" encoding="utf-8" ?> <People> <Person name="Isabella" /> <Person name="Sophia" /> <Person name="Emma" /> <Person name="Olivia" /> <Person name="Ava" /> <Person name="Emily" /> <Person name="Abigail" /> <Person name="Madison" /> <Person name="Chloe" /> <Person name="Mia" /> </People>
続いて T4 Template ファイルをプロジェクトに追加します。T4 Template ファイルの追加は拡張子 tt の テキストファイル(今回は Template.tt)を追加すればOKです。
<#@ template language="C#" hostspecific="true" #> <#@ output extension=".cs" #> <#@ assembly name="System.Core.dll" #> <#@ assembly name="System.Xml.dll" #> <#@ assembly name="System.Xml.Linq.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Xml.Linq" #> using System; namespace T4TemplateSample { public class Program { public static void Main() { <# var xelm = XElement.Load(this.Host.ResolvePath("People.xml")); var query = from t in xelm.Elements("Person") select t; foreach (var t in query) { var name = t.Attribute("name").Value; #> Console.WriteLine("Hello <#= name #>"); <# } #> } } }
今回は Linq to XML を使うので、必要な System.Core.dll、System.Xml.dll、System.Xml.Linq.dll を assembly ディレクティブで読み込み、import ディレクティブで System.Linq、System.Xml.Linq 名前空間をインポートします。
T4 Template ファイルを保存すると、それと同名の CS ファイルにテンプレートの実行結果が出力されます(今回は Template.cs)。
using System; namespace T4TemplateSample { public class Program { public static void Main() { Console.WriteLine("Hello Isabella"); Console.WriteLine("Hello Sophia"); Console.WriteLine("Hello Emma"); Console.WriteLine("Hello Olivia"); Console.WriteLine("Hello Ava"); Console.WriteLine("Hello Emily"); Console.WriteLine("Hello Abigail"); Console.WriteLine("Hello Madison"); Console.WriteLine("Hello Chloe"); Console.WriteLine("Hello Mia"); } } }
以上、すごく普通の内容になりましたけど、仕事ではこれでモデルとかをバリバリ自動生成していきたいなー。
モナドパターン
モナドはメタファーではない: http://eed3si9n.com/ja/monads-are-not-metaphors
「ある物から始めて、その値を使って新たな物を計算するのだ。」
値を格納する型Aを定義して、その型Aに格納した値を使って何かを計算する関数を引数に受けて、計算結果を格納した型Aのインスタンスを返すメソッドを作れば、それはモナドパターンってことでOK?
EPPlus を触ってみた
社内で営業の人が「―Excel を操作するパッケージがあるらしくて、それを使えば―」みたいな電話をしていて、「ああ POI っすね。.NET だと NPOI かな。」と思いながら、その日は自分の仕事をこなしていました。
で、気が向いたので軽く触ってみることにしました。
とりあえず、NPOI を触ってみたんですけど作成できるのは xls ファイルだけ。本家の NPOI は org.apache.poi.xssf パッケージで xlsx ファイルが作れるみたいですけど、NPOI は対応していないみたいですね。xlsx ファイルは ExcelPackage とか EPPlus で作成できるみたいです。で、今回は ExcelPackage より開発が盛ん(?)な EPPlus を触ってみることにしました。
EPPlus: http://epplus.codeplex.com/
バイナリと一緒にサンプルコードがダウンロードできるので、それを参考に大体の機能はすぐ作れそうです。
作るものが何も浮かばなかったので、okazuki さんの NPOI のサンプルコード(http://d.hatena.ne.jp/okazuki/20091128/1259405232)を EPPlus で書き直してみました。
using OfficeOpenXml; using OfficeOpenXml.Style; using OfficeOpenXml.Style.XmlAccess; using System; using System.Drawing; using System.Linq; using System.IO; namespace EPPlusEdu { class Program { static void Main(string[] args) { // output.xlsx の FileInfo を作成する。 FileInfo file = new FileInfo("output.xlsx"); if (file.Exists) { file.Delete(); file = new FileInfo("output.xlsx"); } // Excel 2007 XLSX ファイルパッケージを作成。 using (var package = new ExcelPackage(file)) { // シートを作成 var sheet = package.Workbook.Worksheets.Add("何とかレポート"); // ヘッダーにあたる行を作成 CreateHeaderRow(sheet); // とりあえず10行くらいデータ作成 foreach (var index in Enumerable.Range(1, 10)) CreateRow(sheet, index); // 2列目と3列目は、そのままだと幅が足りないので広げる sheet.Column(2).Width = 12; sheet.Column(3).Width = 16; // output.xlsxに保存 package.Save(); } } // ヘッダー行を作成する private static void CreateHeaderRow(ExcelWorksheet sheet) { // 1列目はIDの列 sheet.Cells[1, 1].Value = "ID"; // 2列目は名前の列 sheet.Cells[1, 2].Value = "名前"; // 3列目は誕生日の列 sheet.Cells[1, 3].Value = "誕生日"; // ヘッダーセルにスタイルを適用する var headerCells = sheet.Cells[1, 1, 1, 3]; // 4方に罫線 headerCells.Style.Border.Top.Style = ExcelBorderStyle.Thin; headerCells.Style.Border.Left.Style = ExcelBorderStyle.Thin; headerCells.Style.Border.Bottom.Style = ExcelBorderStyle.Thin; headerCells.Style.Border.Right.Style = ExcelBorderStyle.Thin; // 薄いグリーンの背景色で塗りつぶす headerCells.Style.Fill.PatternType = ExcelFillStyle.Solid; headerCells.Style.Fill.BackgroundColor.SetColor(Color.LightGreen); // テキストはセンタリング headerCells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; // 太字 headerCells.Style.Font.Bold = true; } private static Random r = new Random(); // index行目のデータを作る private static void CreateRow(ExcelWorksheet sheet, int index) { // id列を作る sheet.Cells[index + 1, 1].Value = index; // 名前も適当に入れて sheet.Cells[index + 1, 2].Value = "田中 太郎" + index; // 誕生日も適当に sheet.Cells[index + 1, 3].Value = DateTime.Now.AddYears(r.Next(10)); // 日付用yyyy年mm月dd日のフォーマットで誕生日は表示するようにする sheet.Cells[index + 1, 3].Style.Numberformat.Format = "yyyy年mm月dd日"; // 全ての列に4方に罫線のあるスタイルを作って適用する var cells = sheet.Cells[index + 1, 1, index + 1, 3]; cells.Style.Border.Top.Style = ExcelBorderStyle.Thin; cells.Style.Border.Left.Style = ExcelBorderStyle.Thin; cells.Style.Border.Bottom.Style = ExcelBorderStyle.Thin; cells.Style.Border.Right.Style = ExcelBorderStyle.Thin; } } }
目新しいことは何もないんですけど、とりあえずこれで今後 Excel 出力の話がでても自信を持って答えられるようになったので、個人的には満足かな。
new PosExplorer() で TypeInitializationException
今後の仕事で使うかなーと思って POS for .NET をサンプルコードを見ながらコーディングしてたら PosExplorer のインスタンス生成で TypeInitializationException の例外が。
PosExplorer posExplorer = new PosExplorer();
えーここでー?使い方間違ってる?これだけだよねー?
InnerException を見てみると、
「このメソッドが明示的に使用する CAS ポリシーは、.NET Framework では使用されなくなっています。互換性のために CAS ポリシーを有効にするには、NetFx40_LegacySecurityPolicy 構成スイッチを使用してください。詳細については、http://go.microsoft.com/fwlink/?LinkID=155570 を参照してください。」
とのこと。ほほう。
.NET 4 から CAS は廃止されたようで、POS for .NET は CAS が有効になっていないとダメみたいです。
で、リンク先の記述のようにアプリケーション構成ファイルに次の設定を追加して無事解消。
<configuration> <runtime> <NetFx40_LegacySecurityPolicy enabled="true"/> </runtime> </configuration>