ラベル iText の投稿を表示しています。 すべての投稿を表示
ラベル iText の投稿を表示しています。 すべての投稿を表示

2011年4月30日土曜日

iTextで移動先の設定する方法

PDF間で特定の位置にリンクする場合、移動先名を設定しないとできません。

iTextで作成する場合、PdfDestinationで飛び先の位置を設定を予め作成したあとにそれぞれのページに追加します。 PdfContentByteもしくはPdfWriterのどちらかから追加できます。また一括でAddNamedDestinationsを使って一括に登録することが可能です。

次は新規文書に移動先を設定する例です。

using System;
using System.Drawing;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace ConsoleApplication1
{
    class Program
    {
        const float pt2mm = 72f / 25.4f;
 
        static void Main(string[] args)
        {
            string savePdf = "hogehoge.pdf";
            string loadPdf = "fugafuga.pdf";
 
            // 新規から作成
            string outputPath = @"hogehoge.pdf";
            Document pdoc = new Document(PageSize.A4);
            PdfWriter pw = PdfWriter.GetInstance(pdoc, new FileStream(outputPath, FileMode.Create));

            // 移動先の場所を設定
            PdfDestination dest = new PdfDestination(PdfDestination.XYZ, 105 * pt2mm, 148.5F * pt2mm, 0);
            
            // コンテンツの書き出し
            pdoc.Open();
            PdfContentByte pcb = pw.DirectContent;
            pcb.LocalDestination("name1", dest);        // 移動先名の作成
            Paragraph p = new Paragraph("Hello World");
            pdoc.Add(p);
            pcb.ClosePath();

            pdoc.NewPage();

            pw.AddNamedDestination("name2", 2, dest);   // 移動先名の作成
            pcb.ClosePath();
            pdoc.Close();
        }
    }
}

だが既存のPDFに追加する場合、新規から作成する場合と同じ設定を行ってもバグなのか分からないが追加することはできません。

仕方が無いので直接命令を書き込みます。
移動先の設定はCatalog→Names→Dests→Namesで取得できます。

PdfReader pdf = new PdfReader(@"hogehoge.pdf");
PdfDictionary root = pdf.Catalog;
PdfDictionary pDests = root.GetAsDict(PdfName.NAMES).GetAsDict(PdfName.DESTS);
PdfArray pDestNames = pDests.GetAsArray(PdfName.NAMES);
if (pDestNames == null)
{
    // 移動先の設定がない場合、作成する
    pDests.Put(PdfName.NAMES, new PdfArray());
    pDestNames = pDests.GetAsArray(PdfName.NAMES);
}

配列に移動先名、移動先の設定の順番に書き込みます。

PdfDestination dest = new PdfDestination(PdfDestination.XYZ, 0, 0, 0);
dest.AddPage(pdf.GetPageOrigRef(1));
pDestNames.Add(new PdfString("name1"));
pDestNames.Add(dest);

まとめると次のとおりになります。

using System;
using System.Drawing;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace ConsoleApplication1
{
    class Program
    {
        const float pt2mm = 72f / 25.4f;
 
        static void Main(string[] args)
        {
            string sourcePdf = @"hogehoge.pdf";
            string outputPath = @"fugafuga.pdf";

            PdfReader pdf = new PdfReader(sourcePdf);
            PdfStamper stamper = new PdfStamper(pdf, new FileStream(outputPath, FileMode.Create));

            // 既存PDFにあれこれ追加
            PdfContentByte cb = stamper.GetUnderContent(1);
            cb.BeginText();
            cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED), 18);
            cb.ShowTextAligned(Element.ALIGN_LEFT, "Sample", 30, 600, 0);
            cb.EndText();

            // 移動先の生成
            PdfDestination dest = new PdfDestination(PdfDestination.XYZ, 0, 0, 0);
            if (dest.HasPage())
                dest.ArrayList[0] = pdf.GetPageOrigRef(2);
            else
                dest.AddPage(pdf.GetPageOrigRef(2));

            // 移動先を設定
            PdfDictionary root = pdf.Catalog;
            PdfDictionary pDests = root.GetAsDict(PdfName.NAMES).GetAsDict(PdfName.DESTS);
            PdfArray pDestNames = pDests.GetAsArray(PdfName.NAMES);
            if (pDestNames == null)
            {
                pDests.Put(PdfName.NAMES, new PdfArray());
                pDestNames = pDests.GetAsArray(PdfName.NAMES);
            }
            pDestNames.Add(new PdfString("name"));
            pDestNames.Add(dest);

            stamper.Close();
            pdf.Close();
        }
    }
}

2010年9月5日日曜日

iTextを使ってPDFの拡大縮小配置

iTextを使ってPDFの縮小、移動などの方法は調べても書かれていそうで意外にもなかったりする。
チュートリアルを見てもアフィン変換を使ってうんぬん・・・と書かれていてさっぱり。(高校の数学で習うらしい)

しかし、JAVAや.netだとそのものずばりのクラスが用意されているので移動、拡大縮小、回転の計算が簡単にできたりします。

次のソースはPDF A4->B5に中央に縮小する例です。(ソースはC#)

using System;
using System.Drawing;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace ConsoleApplication1
{
    class Program
    {
        const float pt2mm = 72f / 25.4f;

        static void Main(string[] args)
        {
            string savePdf = "hogehoge.pdf";
            string loadPdf = "fugafuga.pdf";

            // 新しいPDFファイルの作成
            Document pDoc = new Document(PageSize.A4);
            PdfWriter pw = PdfWriter.GetInstance(pDoc, new System.IO.FileStream(savePdf, System.IO.FileMode.Create));
            pDoc.Open();
            PdfContentByte pcb = pw.DirectContent;
            pDoc.NewPage();

            // 既存PDF読み込む
            PdfReader pr = new PdfReader(loadPdf);
            PdfImportedPage page = pw.GetImportedPage(pr, 1);

            // B5サイズへ縮小
            System.Drawing.Drawing2D.Matrix mtx = new System.Drawing.Drawing2D.Matrix();
            mtx.Scale(0.84f, 0.84f);

            // 用紙中央に移動
            mtx.Translate(14 * pt2mm, 20 * pt2mm, System.Drawing.Drawing2D.MatrixOrder.Append);

            // 新しいPDFに貼り付け
            pcb.AddTemplate(page, mtx);

            pr.Close();
            pDoc.Close();
            pw.Close();
        }
    }
}

JAVAだとAffineTransformという命令を使えばいいらしい。