CodeZine(コードジン)

特集ページ一覧

テキストファイルをRTFテキストに変換してPDF化するアプリケーション

C1PdfDocumentコンポーネントを使ったドキュメント変換アプリの作成

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/11/14 14:00

C1PdfDocumentコンポーネントを使えば、RTFテキストを使ってPDFドキュメントを作成することができます。今回はテキストファイルを読み込み、見出しと文章のフォントサイズや文字色を使い分けてPDFドキュメントにするアプリケーションを作成しました。

はじめに

 C1PdfDocumentコンポーネントを使えば、RTFテキストを使ってPDFドキュメントを作成することができます。今回はテキストファイルを読み込み、見出しと文章のフォントサイズや文字色を使い分けてPDFドキュメントにするアプリケーションを作成しました。

文字列ごとにフォントサイズや文字色を変えてPDFドキュメントにする
文字列ごとにフォントサイズや文字色を変えてPDFドキュメントにする

対象読者

 Visual Basic 2005またはVisual C# 2005を使ってプログラムを作ったことのある人。

必要な環境

 Visual Basic 2005またはVisual C# 2005、Visual Studio 2005でプログラムが作れる環境。

プログラム実行時の注意事項

  • 本稿の実行ファイル(バイナリファイル)を動かすには、zipファイルに同梱してある以下のファイルが必要になります。このファイルを実行プログラムと同じフォルダに格納します。
    • C1.C1Pdf.2.dll…C1Pdf コントロール(.NET Framework 2.0 用)
  • .NET Framework 2.0から追加されたクラスやメンバを使用しているので、.NET Framework 2.0がインストールされていることが必須条件です。
  • 実行ファイルと同梱しているサンプルのテキストファイル「pdf-data.txt」を、ドライブCのルートにおいてください。
  • 作成したPDFドキュメントを表示するためにAdobe Readerを使用しますので、使用しているコンピュータにインストールしておいてください。

コンポーネントのインストール

 はじめてPowerTools True WinReports for .NETおよびPowerTools Preview for .NETを使用する方は、プロジェクトにComponentOne Studio 2007 WinForms Editionをインストールする必要があります。

 インストーラは、グレープシティのWebページからダウンロードできますので、ここからダウンロードしてインストールしてください。製品ページ左側の[ダウンロード]-[トライアル版]をクリックし、ダウンロード方法([FTP]または[HTTP])を選択すれば入手できます。ファイルはLZH形式で圧縮されています。

 有償のコンポーネントですが、プロダクトキーを入力せずにインストールすることで、トライアル版として使用できます。制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。

コントロールの追加

 ComponentOne Studio 2007 WinForms Editionをインストールしたら、ツールボックスに専用のタブを作成し、PowerTools PDF for .NET を追加します。追加するコンポーネントは、「.NET Frameworkコンポーネント」の「名前空間」が「C1.C1Pdf」で始まる名前空間のコンポーネント「C1PdfDocument」です。

「名前空間」が「C1.C1Pdf」で始まる名前空間のコンポーネント「C1PdfDocument」を選択する
「名前空間」が「C1.C1Pdf」で始まる名前空間のコンポーネント「C1PdfDocument」を選択する
※注意
 Visual Studio .NET 2002/2003用コンポーネントとVisual Studio 2005用コンポーネントは、コンポーネント名や名前空間がほとんど同じですが、Visual Studio .NET 2002/2003用コンポーネントをVisual Studio 2005環境で使うことはできないので、間違えないようにしてください。
 Visual Studio 2005用コンポーネントは、アセンブリ名が「C1.C1Pdf.2 」と末尾に「.2」が付いているので、必ずアセンブリ名を確認し、コンポーネントを選択してください。

GUIの作成

 フォームはButtonを2つとTextBoxを1つ、C1PdfDocumentコンポーネントを1つ配置する簡単なものです。

 C1PdfDocumentコンポーネントは機能を提供するコンポーネントで、ユーザーの操作は受け付けませんのでフォームの外に配置されます。TextBoxは、Multilineプロパティを「True」にし、ScrollBarsプロパティを「Vertical」に設定しておきます。

GUIデザイン
GUIデザイン

 なお、PowerTools PDF for .NETのC1PdfDocumentコンポーネントについての説明は、前回の記事を参照してください。

簡単なRTFテキストのPDF化処理の作成 1

 まずはじめに、簡単なRich Text Formatで作成した文字列をPDF化する処理を作成してみましょう。

 この処理は、ボタン「簡単な rtf 出力」のClickイベントハンドラに作成します。RTFは、HTMLのように専用のタグをテキストデータの前後に付けることで、RTFリーダーアプリケーションがこのタグを解釈して文字の装飾などを行います。

 そこで、RTFテキストを作成する方法を知るために、簡単な文字列を使ってテキスト装飾機能を試してみます。

太字・斜体・文字色・タブの機能を組み込んだPDFドキュメントを作成する
太字・斜体・文字色・タブの機能を組み込んだPDFドキュメントを作成する

RTFタグについて

 RTFのタグは、HTMLのようなスタイルを持ち、フォントやカラー、テーブルなどを自在に操作できるようになっています。基本的には、装飾を実施したい文字列を{}で囲み、\記号とタグ名、パラメータを指定します。

 例えば、「boldly」という文字を太字にしたければ、

Visual Basic
{\b boldly}
C#
{\\b boldly} 

 と記述します。C#では\記号を表すために\\と記述する点に注意してください。

 また、フォントサイズを40にしたければ、

Visual Basic
{\fs40 boldly}
C#
{\\fs40 boldly} 

 と記述します。\fsがタグで、「40」がパラメータです。

 1つの文字列に複数の装飾を施したい場合があります。その場合は、タグごとに{}で括ります。例えば、「no one」という文字列に斜体・フォントサイズ40・文字色を青、という装飾を適用するには、次のように記述します。

Visual Basic
{\i {\fs40 {\cf2 no one }}} 
C#
{\\i {\\fs40 {\\cf2 no one }}}

 \iは文字を斜体にするタグです。\cfはカラーテーブルにある色を指定するタグで、「2」が青色を表すカラーテーブルの番号です(カラーテーブルについてはこのあと説明します)。

 最初のタグの{}の中に、次のタグを{付きで記述し、文字列の終端に{の数だけ}をつけます。必ず、{}の数が一致するように記述してください。数が不一致だと正常に文章を出力できなくなります。

 文字列を改行するには、エスケープシーケンスのCR・LFではなく、\parというタグを使用します。このタグだけは{}を必要としません。今の文字列の終端で改行したければ、次のように記述します。

Visual Basic
{\i {\fs40 {\cf2 no one \par}}} 
C#
{\\i {\\fs40 {\\cf2 no one \\par}}}

 このように、装飾したい文字列ごとに{}で括り、タグとパラメータがあるものはそのデータを記述していきます。

簡単なRTFテキストのPDF化処理の作成 2

カラーテーブルの作成

 文字色や線などにカラーを使用するには、RTFファイルごとにカラーテーブルを作成する必要があります。そして、色を指定するタグでは、このカラーテーブルの中からどの色を使用するのかを、パレットの中のその色がある位置を番号で指定します。

 通常、WordなどのRTF対応アプリケーションでは、入力文書をファイルに保存する際、リッチテキストフォーマットの先頭にカラーテーブルを作成してくれるので特にユーザーが作成する必要はありません。しかし、自作でRTFドキュメントを作成する場合は、ドキュメント内で使用する色のリストをカラーテーブルとして作成する必要があります。

 カラーテーブルは、\colortblというタグと、色をRGBで表すための\red\green\blueの4つのタグを使用します。

 例えば、黒色を使用したければ、

{\colortbl;\red0\green0\blue;}

 と記述します。黒と白の2色を使いたければ、\red\green\blueタグの記述を;で区切って2個作成します。

{\colortbl;\red0\green0\blue0;\red255\green255\blue255;}

 こうして、使いたい色の数だけ\red\green\blueタグの記述を;で区切って作成します。

 次のコードは、15色のカラーテーブルを作成します。

{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255
\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0
\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0
\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0
\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128
\green128\blue128;}

 カラーテーブルの色を使用する場合は、その位置を番号で指定します。このカラーテーブルの青色を使いたければ、2番目の\red0\green0\blue255を指定します。

 カラーテーブルは、必ず1行で作成し、行末は;}で終わるようにします。そして、RTF化する文字列の先頭に記述します。

PDF作成の準備

 では、処理を組み立てていきましょう。

 最初に、PDF化の準備処理を作成します。まず、2つの名前空間への参照を宣言しておきます。C#は、デフォルトで「System.Text」への参照が設定されていますから、「System.IO」だけ参照するようにします。

 そして、PDFドキュメントに使用するフォントと描画領域を作成します。

Visual Basic
Imports System.IO
Imports System.Text

Private Sub Button1_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button1.Click
    Dim font As New Font("MSゴシック", 12)
    Dim rc As RectangleF = Me.C1PdfDocument1.PageRectangle
    rc.Inflate(-72, -72)
C#
using System.IO;

private void Button1_Click(object sender, EventArgs e)
{
    Font font = new Font("MSゴシック", 12);
    RectangleF rc = c1PdfDocument1.PageRectangle;
    rc.Inflate(-72, -72);

 次に、カラーテーブルを作成します。今回は、8色のテーブルを作ります。1行の文字列にして、変数に格納します。

Visual Basic
Dim s As String
    s = "{\colortbl;\red0\green0\blue0;\red0\green0\blue255;" & _
          "\red0\green255\blue255;\red0\green255\blue0;" & _
          "\red255\green0\blue255;\red255\green0\blue0;" & _
          "\red255\green255\blue0;\red255\green255\blue255;}"
C#
String s;  
    s = "{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;" +
      "\\red0\\green255\\blue255;\\red0\\green255\\blue0;" +
      "\\red255\\green0\\blue255;\\red255\\green0\\blue0;" +
      "\\red255\\green255\\blue0;\\red255\\green255\\blue255;}";

 そして、表示する文字列にタグをつけます。使用する文字列はなんでも構いませんが、ここでは「To boldly go where no one has gone before!」という英文を使用しています。

 文字とタグの間にスペースを入れて、RTFリーダーアプリケーションがきちんとタグを認識できるようにしてください。

Visual Basic
s &= "To {\b boldly} {\tab go where} 
{\i {\fs40 {\cf2 no one \par}}} has {\cf6 gone before!}"
C#
s += "To {\\b boldly} {\\tab go where} 
{\\i {\\fs40 {\\cf2 no one \\par}}} has {\\cf6 gone before!}";

 最後に、作成したRTFテキストを、C1PdfDocumentコンポーネントのDrawStringRtfメソッドの引数に指定して実行します。DrawStringRtfメソッドは、DrawStringメソッドと同じようなメソッドですが、指定する文字列がRTFテキストになっています。

 そして、PDF文書の保存と表示を実行します。この部分は前回作成したものとほぼ同じ処理をサブルーチンにまとめています。

Visual Basic
Me.C1PdfDocument1.DrawStringRtf(s, font, Brushes.Black, rc)
savepdf()
C#
c1PdfDocument1.DrawStringRtf(s, font, Brushes.Black, rc);
savepdf();
文字単位で装飾を変えたり、タブ移動や改行が行える
文字単位で装飾を変えたり、タブ移動や改行が行える

テキストファイルを読み込んでRTF化を実行する処理

 今度は、テキストファイルを読み込んで、RTFテキストに変換してPDFドキュメント化する処理を作ります。

 テキストファイルは、画面のように大見出し、中見出し、小見出しを◆◇▲の記号で区別し、特に色を変えたい行には※記号をつけています。

テキストは記号で装飾の違いを区別している
テキストは記号で装飾の違いを区別している

 プログラム側では、この記号を識別しRTFタグの設定を変えるようにしています。

このような形でRTFテキスト化する
このような形でRTFテキスト化する

 この処理は、ボタン「読み込み」のイベントハンドラに作成します。

※注意
 サンプルのテキストファイル「pdf-data.txt」を、ドライブCのルートにおいてからプログラムを実行してください。

PDF作成の準備

 最初に、PDF作成のための各種設定を行います。ここは、先に作成したプログラムと同じようなコードです。一部数値と変数の数が変わっています。カラーテーブルも、色数を1つ増やしています。

 配列buff()は、ファイルから読み込んだテキストを格納するのに使用します。

Visual Basic
Private Sub Button2_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button2.Click
    Dim font As New Font("MS ゴシック", 10)

    Dim rc As RectangleF = Me.C1PdfDocument1.PageRectangle
    rc.Inflate(-50, -50)

    Dim buff() As String, str As String = ""
    Dim c As String = ""

    str = "{\colortbl;\red0\green0\blue0;\red0\green0\blue255;" & _
      "\red0\green255\blue255;\red0\green255\blue0;" & _
      "\red255\green0\blue255;\red255\green0\blue0;" & _
      "\red255\green255\blue0;\red255\green255\blue255;" & _
      "\red126\green94\blue225;}"
C#
private void button2_Click(object sender, EventArgs e)
{
    Font font = new Font("MS ゴシック", 10);

    RectangleF rc = c1PdfDocument1.PageRectangle;
    rc.Inflate(-50, -50);

    String[] buff;
    String str  = "";
    String c = "";
    String msg = "";

    str = "{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;" +
      "\\red0\\green255\\blue255;\\red0\\green255\\blue0;" +
      "\\red255\\green0\\blue255;\\red255\\green0\\blue0;" +
      "\\red255\\green255\\blue0;\\red255\\green255\\blue255;" +
      "\\red126\\green94\\blue225;}";

テキストファイルの読み込み処理

 続いて、テキストファイルを読み込んでデータを取得する処理です。テキストファイルからの読み込みには、FileクラスのReadAllLinesメソッドを使用します。

 Fileクラスは、ファイルの作成、コピー、削除、移動、オープンなどファイルの操作のための静的メソッドを提供するクラスです。メソッドの提供のみのクラスなのでコンストラクタによるオブジェクトインスタンスの作成は必要ありません。

 ReadAllLinesメソッドは、ファイルを開き中のデータを行単位で取り出して配列に格納するメソッドです(行単位とは、改行コードに出会うまでを1行としています)。引数は2つで、1つは読み出すファイルへのパス名で、もう1つは文字のエンコーディングをEncodingクラスのメンバで指定します。「Default」を指定すると、システムの現在のANSIコードページのエンコーディングを使用してデータを取り出します。

Visual Basic
buff = File.ReadAllLines("c:\pdf-data.txt", Encoding.Default)
C#
buff = File.ReadAllLines("c:/pdf-data.txt", Encoding.Default);

 取り出したテキストデータは、1行ずつ配列Buffの要素に格納されているので、VBではFor Each...Nextステートメントで、C#であればforeachステートメントを使って1行ずつ参照し、文字列の先頭にある記号を取りだして、処理を分岐します。文字の取り出しは、StringクラスのSubstringメソッドを使用します。なお、配列には元のテキストファイルにある改行分も要素に格納されていますが、中身は空なのでデータのある場合だけ先頭の1文字を取り出します。

Visual Basic
For Each s In buff
    If s <> "" Then
        c = s.Substring(0, 1)
        Select Case c
C#
foreach (String s in buff)
{
    if (s != "")
    {
        c = s.Substring(0, 1);
        switch (c)

 先頭の文字を取り出したら、後はそれぞれの書式になるようにRTFタグを設定します。先頭の記号はPDFドキュメントには必要ないので、StringクラスのRemoveメソッドで切り取っておきます。

 そして、すべての行がカラーテーブルの記述を含め1行の文字列になるようにして変数strに格納します。このとき、空白の要素がある場合は、改行するように{\par }を結合しておきます。

Visual Basic
            Case "◆"
                s = s.Remove(0, 1)
                str &= "{\b {\fs30 {\cf2 " & s & " \par}}} "
            Case "◇"
                s = s.Remove(0, 1)
                str &= "{\fs26 {\cf6 \tab " & s & " \par}} "
            Case "▲"
                s = s.Remove(0, 1)
                str &= "{\fs26 {\cf9 " & s & " \par}} "
            Case "※"
                s = s.Remove(0, 1)
                str &= "{\cf5 \tab " & s & " \par} "
            Case Else
                str &= "{\cf0  " & s & " \par }"
        End Select
    Else
        str &= "{\par }"
    End If
Next
C#
        {
            case "◆":
                msg = s.Remove(0, 1);
                str += "{\\b {\\fs30 {\\cf2 " + msg + " \\par}}} ";
                break;
            case "◇":
                msg = s.Remove(0, 1);
                str += "{\\fs26 {\\cf6 \\tab " + msg + " \\par}} ";
                break;
            case "▲":
                msg = s.Remove(0, 1);
                str += "{\\fs26 {\\cf9 " + msg + " \\par}} ";
                break;
            case "※":
                msg = s.Remove(0, 1);
                str += "{\\cf5 \\tab " + msg + " \\par} ";
                break;
            default:
                str += "{\\cf0  " + s + " \\par }";
                break;
         }
    }
    else
    {
        str += "{\\par }";
    }
}

 最後に、C1PdfDocumentコンポーネントのDrawStringRtfメソッドを実行してRTFテキストをPDF化し、保存と表示処理を実行して出来上がりです。

 なお、このプログラムでは、作成したRTFテキストがどのようになっているのかが分かるように、TextBoxで表示するようにしています。

Visual Basic
Me.C1PdfDocument1.DrawStringRtf(str, font, Brushes.Black, rc)
Me.TextBox1.Text = str
savepdf()
C#
c1PdfDocument1.DrawStringRtf(str, font, Brushes.Black, rc);
textBox1.Text = str;
savepdf();

まとめ

 RTFテキストは、プレーンのテキストに比べて綺麗な装飾を設定できるのがメリットですが、そのためにタグを設定しなければならないのがちょっとやっかいです。しかし、同じPDFドキュメントを作成するなら、綺麗に装飾されたドキュメントの方が見栄えがよくアピール度も高くなります。

 C1PdfDocumentコンポーネントは、RTFドキュメントもPDF化できますから、RTFエディタにPDF化処理を組み込めば、機能の高いアプリケーションを作ることができると思います。

参考文献

  • Microsoft Dpownload Center『Word 2007: Rich Text Format (RTF) Specification, version 1.9
  • このドキュメントでは、「\」(英語キーボードではバックスラッシュ)を「Control Symbol」、「tab」や「fb」などの命令記号を「Destinations」、「{}」を「Group」と呼び、これらを総称して「Control Word」と呼んでいますが、本稿では記事の内容を分かりやすくするために「タグ」という用語に置き換えて記述しています。
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 瀬戸 遥(セト ハルカ)

    8ビットコンピュータの時代からBASICを使い、C言語を独習で学びWindows 3.1のフリーソフトを作成、NiftyServeのフォーラムなどで配布。Excel VBAとVisual Basic関連の解説書を中心に現在まで40冊以上の書籍を出版。近著に、「ExcelユーザーのためのAccess再...

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5