ディーバ Blog

大阪発 C#の会社、株式会社ディーバの Blog です。

iTextSharp で外字を PDF に出力

少しだけ iTextSharp と日本語外字を扱ったのでメモ。

DirectContent を使う場合

外字ファイルを指定した BaseFont オブジェクトを生成します。DirectContent.ShowTextAligned メソッドを使うと自由な位置にテキストを出力できますが、指定できるフォントがひとつのため外字しか出力できません。

外字ファイル EUDC.TTE をコピーして拡張子を TTF へリネームすると扱えるようです。

TechPress » iTextSharpで外字を利用する方法 を参考にしました。

//using iTextSharp.text;
//using iTextSharp.text.pdf;
//using System;
//using System.IO;
//using System.Linq;
//using System.Text;

private static void Sample1()
{
    var eudcPath = "EUDC.TTF";
    File.Copy(@"c:\Windows\Fonts\EUDC.TTE", eudcPath, true); // 外字ファイルをコピー・リネーム
    var eudcBaseFont = BaseFont.CreateFont(eudcPath, BaseFont.IDENTITY_H, true);

    var doc = new Document();
    var writer = PdfWriter.GetInstance(doc, new FileStream("sample1.pdf", FileMode.Create));
    doc.Open();

    var cb = writer.DirectContent;
    cb.BeginText();
    cb.SetFontAndSize(eudcBaseFont, 12);
    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "外字テキスト", 100, 100, 0);
    cb.EndText();

    doc.Close();
}

Phrase を使う場合

通常のテキストと外字テキストでフォントの指定を変えた Phrase オブジェクトを生成します。

ゆめみるうみそら 夢見海空 » itextSharpで日本語外字の対応 を参考にしました(ほとんどそのままです)。

//using iTextSharp.text;
//using iTextSharp.text.pdf;
//using System;
//using System.IO;
//using System.Linq;
//using System.Text;

private static void Sample2()
{
    var normalFont = new Font(BaseFont.CreateFont(@"c:\Windows\Fonts\msgothic.ttc,0", BaseFont.IDENTITY_H, true), 12, Font.NORMAL, new BaseColor(0, 0, 0));

    var eudcPath = "EUDC.TTF";
    File.Copy(@"c:\Windows\Fonts\EUDC.TTE", eudcPath, true); // 外字ファイルをコピー・リネーム
    var eudcFont = new Font(BaseFont.CreateFont(eudcPath, BaseFont.IDENTITY_H, true), 12, Font.NORMAL, new BaseColor(0, 0, 0));

    var doc = new Document();
    var writer = PdfWriter.GetInstance(doc, new FileStream("sample2.pdf", FileMode.Create));
    doc.Open();

    var p = CreatePhrase("外字を含むテキスト", normalFont, eudcFont);
    doc.Add(p);

    doc.Close();
}

private static Phrase CreatePhrase(string s, Font normalFont, Font eudcFont)
{
    var p = new Phrase();
    foreach (var c in s)
    {
        var buf = Encoding.GetEncoding("Shift_JIS").GetBytes(c.ToString());
        var code = BitConverter.ToUInt16(buf.Reverse().ToArray(), 0);
        var font = (code >= 0xF000 && code <= 0xFFFC) ? eudcFont : normalFont;
        p.Add(new Chunk(c, font));
    }
    return p;
}

フォント フォルダーをエクスプローラーで開く

フォントフォルダー(通常 c:\Windows\Fonts)をエクスプローラーで開くと、特殊な表示になってしまい、実ファイルを参照できません。

ファイルを参照したい場合、パスを \\コンピューター名\c$\Windows\Fonts としてアクセスするテクニックがあるようです。

「Visual Studio 2017 先取り特集」連載の「Visual Studio for Mac」紹介記事が公開されています

2016/2/15、CodeZine で 次期バージョン「Visual Studio 2017(Visual Studio “15")」先取り特集 第3回『使う言語はC#のみ! Macアプリケーションはもちろん、Webアプリやスマホアプリも開発可能な「Visual Studio for Mac」登場』が公開されています。

この第3回は、株式会社ディーバ 代表取締役 青柳臣一が担当しています。

対象読者は次の通り。ご興味のある方はどうぞ。

  • Macでアプリケーション開発をおこなっている方
  • Visual Studioでアプリケーション開発をおこなっていてMacでも開発をおこないたい方
  • Xamarinでの開発をおこなっている方

codezine.jp

PowerShell でディスプレイの解像度を変更

Microsoft スクリプト センター にある Set-ScreenResolution のコードが使えます。2010年に投稿されたものですが、Windows 10 でも動作を確認。

gallery.technet.microsoft.com

コードの内容は、プライマリモニタの解像度を変更します。Win32 API の ChangeDisplaySettings を呼び出しています。使い方は、次の通り。

Set-ScreenResolution -Width 1024 -Height 768       

C# で日本の祝日を取得

C# で日本の祝日を扱います。

f:id:jz5_diva:20170208121003p:plain

取得しない

もっとも簡単で処理的にも速いのは、あらかじめ登録しておくことですよね。常にメンテナンスするような Web サービスであれば、これが一番いいかも。実際、大手グループウェアで数年先のカレンダーを見ると祝日が未設定だったりします。

var holidays = new HashSet<DateTime>()
{
    new DateTime(2017, 1, 1),
    new DateTime(2017, 1, 2),
    new DateTime(2017, 1, 9),
    new DateTime(2017, 2, 11),
    new DateTime(2017, 3, 20),
    new DateTime(2017, 4, 29),
    new DateTime(2017, 5, 3),
    new DateTime(2017, 5, 4),
    new DateTime(2017, 5, 5),
    new DateTime(2017, 7, 17),
    new DateTime(2017, 8, 11),
    new DateTime(2017, 9, 18),
    new DateTime(2017, 9, 23),
    new DateTime(2017, 10, 9),
    new DateTime(2017, 11, 3),
    new DateTime(2017, 11, 23),
    new DateTime(2017, 12, 23),
};

Google カレンダーを利用

でもメンテしたくない、実装も簡単にしたいってことで、Google カレンダーから祝日を得るようにしてみます。Google Calendar API を使って祝日を取る PHP編 - Qiita を参考にして、C# で書いて見ました。

Newtonsoft.Json を利用しています。API については元記事を参照してください。

public static async Task<HashSet<DateTime>> GetHolidaysAsync(int year)
{
    var key = "API_KEY";
    var holidaysId = "japanese__ja@holiday.calendar.google.com";
    var startDate = new DateTime(year, 1, 1).ToString("yyyy-MM-dd") + "T00%3A00%3A00.000Z";
    var endDate = new DateTime(year, 12, 31).ToString("yyyy-MM-dd") + "T00%3A00%3A00.000Z";
    var maxCount = 30;

    var url = $"https://www.googleapis.com/calendar/v3/calendars/{holidaysId}/events?key={key}&timeMin={startDate}&timeMax={endDate}&maxResults={maxCount}&orderBy=startTime&singleEvents=true";
    var client = new WebClient() { Encoding = System.Text.Encoding.UTF8 };
    var json = await client.DownloadStringTaskAsync(url);
    client.Dispose();

    var o = JObject.Parse(json);
    var days = o["items"].Select(i => DateTime.Parse(i["start"]["date"].ToString()));
    return new HashSet<DateTime>(days);
}

次のように使うと最初のコードと同じ結果が得られます。

var holidays = await GetHolidaysAsync(2017);

Excel でシートを別のブックにコピーや移動すると日付が変わる

Excel でシートをコピーや移動すると、日付の値が変わることがあります(!)。

f:id:jz5_diva:20170203182755p:plain

原因は、日付を1900年を基準として扱うか、1904年を基準として扱うかが、ブック間で異なるからです。

Excel のオプション(「ファイル」タブから「オプション」)の「詳細設定」にある「1904年から計算する」の設定を確認してみてください。

f:id:jz5_diva:20170203183143p:plain

参考: Excel の 1900 年を基準とした日付方式と 1904 年を基準とした日付方式の違いについて

C# で国名の一覧を取得・表示する

CultureInfo, RegionInfo を使って国名(台湾・香港なども含む)の一覧を取得します。アプリで国籍の選択などに使えるかなと。

GetCultures でカルチャを取得し、LCID(ロケールID)プロパティを使って RegionInfo を生成します。Name プロパティが2文字のオブジェクトのみ使います。2文字の値は、ISO 3166 の国名コードです。2文字以外の値には “001” (世界)・"029" (カリブ)・"419" (ラテン アメリカ) があります。

var names = CultureInfo
    .GetCultures(CultureTypes.SpecificCultures)
    .Where(c => c.LCID != 4096 /* LOCALE_CUSTOM_UNSPECIFIED を除く */)
    .Select(c => new RegionInfo(c.LCID))
    .Where(r => r.Name.Length == 2)
    .Distinct()
    .OrderBy(r => r.DisplayName)
    .ToDictionary(r => r.Name, r => r.DisplayName);

Windows 10 で実行した結果です。139件ありました。

f:id:jz5_diva:20170120132840p:plain

すべての国が定義されているわけではないようです。CultureInfo.CreateSpecificCulture Method (String) (System.Globalization) の Remarks によると、Windows で定義されている一覧は [MS-LCID]: Appendix A: Product Behavior で参照できます。

参考として Wikipedia の 国の一覧 - Wikipedia では206ヶ国掲載されています。日本政府が承認した国家数は195ヶ国(日本除く)です。

他のサービスの国数も調べてみました。

  • Microsoft アカウントの国/地域は、254個
  • Google アカウントの国/地域は、255個
  • Tiwtter プロフィールの国は、155個と「世界中」

ディーバは、エクセルソフト「Xamarin 開発支援サービス」のパートナー企業です

株式会社ディーバは、エクセルソフト株式会社の提供する「Xamarin 開発支援サービス」の パートナー企業 に登録されました。

Xamarin 開発支援サービスについて

2017年1月11日 Xamarin 開発支援サービス プレスリリース より。

エクセルソフトは、Xamarin のエキスパートであるパートナー企業と提携し、モバイル アプリの開発支援サービスを提供開始

エクセルソフト株式会社(東京都港区)は、マイクロソフト社の Visual Studio に統合され、クロスプラットフォーム モバイル アプリの開発環境としてますます注目を集めている Xamarin のエキスパートでモバイル アプリの開発実績のあるパートナー企業と提携し、モバイル アプリの開発支援サービスを 2017 年 1 月 11 日より日本国内で提供開始しました。

株式会社ディーバについて

大阪発 C# の会社「株式会社ディーバ」は、平成4年創立以来 、最新の技術を自分たち自身で確かめ、その技術を元にお客様のさまざまなニーズに幅広くお答えしてきました。Xamarin を活用し最新技術を駆使した iOS / Android / Windows モバイルアプリケーションおよびデスクトップアプリケーション、さらにはサーバーアプリケーションも含めて幅広いソフトウエア開発ソリューションをご提供いたします。

詳細は以下のページをご参照ください。 株式会社ディーバ