はじめに
C1PdfDocumentコンポーネントを使えば、RTFテキストを使って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」です。
Visual Studio 2005用コンポーネントは、アセンブリ名が「C1.C1Pdf.2 」と末尾に「.2」が付いているので、必ずアセンブリ名を確認し、コンポーネントを選択してください。
GUIの作成
フォームはButtonを2つとTextBoxを1つ、C1PdfDocumentコンポーネントを1つ配置する簡単なものです。
C1PdfDocumentコンポーネントは機能を提供するコンポーネントで、ユーザーの操作は受け付けませんのでフォームの外に配置されます。TextBoxは、Multilineプロパティを「True」にし、ScrollBarsプロパティを「Vertical」に設定しておきます。
なお、PowerTools PDF for .NETのC1PdfDocumentコンポーネントについての説明は、前回の記事を参照してください。
簡単なRTFテキストのPDF化処理の作成 1
まずはじめに、簡単なRich Text Formatで作成した文字列をPDF化する処理を作成してみましょう。
この処理は、ボタン「簡単な rtf 出力」のClickイベントハンドラに作成します。RTFは、HTMLのように専用のタグをテキストデータの前後に付けることで、RTFリーダーアプリケーションがこのタグを解釈して文字の装飾などを行います。
そこで、RTFテキストを作成する方法を知るために、簡単な文字列を使ってテキスト装飾機能を試してみます。
RTFタグについて
RTFのタグは、HTMLのようなスタイルを持ち、フォントやカラー、テーブルなどを自在に操作できるようになっています。基本的には、装飾を実施したい文字列を{}
で囲み、\
記号とタグ名、パラメータを指定します。
例えば、「boldly」という文字を太字にしたければ、
{\b boldly}
{\\b boldly}
と記述します。C#では\
記号を表すために\\
と記述する点に注意してください。
また、フォントサイズを40にしたければ、
{\fs40 boldly}
{\\fs40 boldly}
と記述します。\fs
がタグで、「40」がパラメータです。
1つの文字列に複数の装飾を施したい場合があります。その場合は、タグごとに{}
で括ります。例えば、「no one」という文字列に斜体・フォントサイズ40・文字色を青、という装飾を適用するには、次のように記述します。
{\i {\fs40 {\cf2 no one }}}
{\\i {\\fs40 {\\cf2 no one }}}
\i
は文字を斜体にするタグです。\cf
はカラーテーブルにある色を指定するタグで、「2」が青色を表すカラーテーブルの番号です(カラーテーブルについてはこのあと説明します)。
最初のタグの{}
の中に、次のタグを{付きで記述し、文字列の終端に{
の数だけ}
をつけます。必ず、{}
の数が一致するように記述してください。数が不一致だと正常に文章を出力できなくなります。
文字列を改行するには、エスケープシーケンスのCR・LFではなく、\par
というタグを使用します。このタグだけは{}
を必要としません。今の文字列の終端で改行したければ、次のように記述します。
{\i {\fs40 {\cf2 no one \par}}}
{\\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ドキュメントに使用するフォントと描画領域を作成します。
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)
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行の文字列にして、変数に格納します。
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;}"
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リーダーアプリケーションがきちんとタグを認識できるようにしてください。
s &= "To {\b boldly} {\tab go where}
{\i {\fs40 {\cf2 no one \par}}} has {\cf6 gone before!}"
s += "To {\\b boldly} {\\tab go where} {\\i {\\fs40 {\\cf2 no one \\par}}} has {\\cf6 gone before!}";
最後に、作成したRTFテキストを、C1PdfDocumentコンポーネントのDrawStringRtfメソッドの引数に指定して実行します。DrawStringRtfメソッドは、DrawStringメソッドと同じようなメソッドですが、指定する文字列がRTFテキストになっています。
そして、PDF文書の保存と表示を実行します。この部分は前回作成したものとほぼ同じ処理をサブルーチンにまとめています。
Me.C1PdfDocument1.DrawStringRtf(s, font, Brushes.Black, rc)
savepdf()
c1PdfDocument1.DrawStringRtf(s, font, Brushes.Black, rc); savepdf();
テキストファイルを読み込んでRTF化を実行する処理
今度は、テキストファイルを読み込んで、RTFテキストに変換してPDFドキュメント化する処理を作ります。
テキストファイルは、画面のように大見出し、中見出し、小見出しを◆◇▲の記号で区別し、特に色を変えたい行には※記号をつけています。
プログラム側では、この記号を識別しRTFタグの設定を変えるようにしています。
この処理は、ボタン「読み込み」のイベントハンドラに作成します。
PDF作成の準備
最初に、PDF作成のための各種設定を行います。ここは、先に作成したプログラムと同じようなコードです。一部数値と変数の数が変わっています。カラーテーブルも、色数を1つ増やしています。
配列buff()は、ファイルから読み込んだテキストを格納するのに使用します。
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;}"
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コードページのエンコーディングを使用してデータを取り出します。
buff = File.ReadAllLines("c:\pdf-data.txt", Encoding.Default)
buff = File.ReadAllLines("c:/pdf-data.txt", Encoding.Default);
取り出したテキストデータは、1行ずつ配列Buffの要素に格納されているので、VBではFor Each...Nextステートメントで、C#であればforeachステートメントを使って1行ずつ参照し、文字列の先頭にある記号を取りだして、処理を分岐します。文字の取り出しは、StringクラスのSubstringメソッドを使用します。なお、配列には元のテキストファイルにある改行分も要素に格納されていますが、中身は空なのでデータのある場合だけ先頭の1文字を取り出します。
For Each s In buff If s <> "" Then c = s.Substring(0, 1) Select Case c
foreach (String s in buff) { if (s != "") { c = s.Substring(0, 1); switch (c)
先頭の文字を取り出したら、後はそれぞれの書式になるようにRTFタグを設定します。先頭の記号はPDFドキュメントには必要ないので、StringクラスのRemoveメソッドで切り取っておきます。
そして、すべての行がカラーテーブルの記述を含め1行の文字列になるようにして変数strに格納します。このとき、空白の要素がある場合は、改行するように{\par }
を結合しておきます。
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
{ 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で表示するようにしています。
Me.C1PdfDocument1.DrawStringRtf(str, font, Brushes.Black, rc) Me.TextBox1.Text = str savepdf()
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』
- Microsoft サポートオンライン『ASP を使用して RTF (Rich Text Format) ドキュメントを生成し、Microsoft Word にストリーム出力する方法』