以前、「iTextSharpで日本語出力」を紹介しましたが、今回は複数のPDFファイルを選択して、それらを結合出力する方法をご紹介します。
とりあえず単純に結合
今回もフォームはシンプルにこんな感じ
以下がソース
private void btnJoin_Click(object sender, EventArgs e)
{
string joinPdfPath = "C:\\join.pdf";
// ファイル選択ダイアログを表示
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "PDFファイル(*.pdf)|*.pdf";
ofd.Title = "結合するPDFを選択してください";
ofd.Multiselect = true; // 複数ファイル選択
if (ofd.ShowDialog() == DialogResult.OK)
{
// PDFドキュメント作成
Document joinDc = new Document();
// 結合先PDFファイルの作成
FileStream joinFs = new FileStream(joinPdfPath, FileMode.Create, FileAccess.Write);
// 結合先PDFオブジェクトとPDFファイルの関連付け
PdfWriter joinWr = PdfWriter.GetInstance(joinDc, joinFs);
// 結合先PDFオープン
joinDc.Open();
// PdfContentByte取得
PdfContentByte joinPcb = joinWr.DirectContent;foreach (string fn in ofd.FileNames)
foreach(string fileName in ofd.FileNames)
{
// ファイル読み込み
PdfReader joinRd = new PdfReader(File.ReadAllBytes(fileName));
// 結合元PDFファイルのページ数取得
int joinNp = joinRd.NumberOfPages;
for (int joinPageNum = 1; joinPageNum <= joinNp; joinPageNum++)
{
// ページサイズ設定
joinDc.SetPageSize(joinRd.GetPageSizeWithRotation(joinPageNum));
// 改ページ
joinDc.NewPage();
// ページ取得
PdfImportedPage joinPage = joinWr.GetImportedPage(joinRd, joinPageNum);
// ページ結合
joinPcb.AddTemplate(joinPage,0,0);
}
}
// 結合先PDFクローズ
joinDc.Close();
}
}
これで複数選択したファイルを結合完了するはず!
と、思いきや、思わぬ落とし穴。
PDFは実は回転情報があるので、これだと90度回転とかしているPDFファイルだといきなり横向きのPDFが縦向きに結合されてしまう現象が起きます。
これではいかんよねぇ・・・。
なので改良して結合
対応するには無回転、90度回転、180度回転、270度回転それぞれの対応が必要となる。
対応したソースは以下の通り
private void btnJoin_Click(object sender, EventArgs e)
{
string joinPdfPath = "C:\\join.pdf";
// ファイル選択ダイアログを表示
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "PDFファイル(*.pdf)|*.pdf";
ofd.Title = "結合するPDFを選択してください";
ofd.Multiselect = true; // 複数ファイル選択
if (ofd.ShowDialog() == DialogResult.OK)
{
// PDFドキュメント作成
Document joinDc = new Document();
// 結合先PDFファイルの作成
FileStream joinFs = new FileStream(joinPdfPath, FileMode.Create, FileAccess.Write);
// 結合先PDFオブジェクトとPDFファイルの関連付け
PdfWriter joinWr = PdfWriter.GetInstance(joinDc, joinFs);
// 結合先PDFオープン
joinDc.Open();
// PdfContentByte取得
PdfContentByte joinPcb = joinWr.DirectContent;foreach (string fn in ofd.FileNames)
foreach(string fileName in ofd.FileNames)
{
// ファイル読み込み
PdfReader joinRd = new PdfReader(File.ReadAllBytes(fileName));
// 結合元PDFファイルのページ数取得
int joinNp = joinRd.NumberOfPages;
for (int joinPageNum = 1; joinPageNum <= joinNp; joinPageNum++)
{
// ページ回転向き取得
int pageRotation = joinRd.GetPageRotation(1);
// ページサイズ設定
joinDc.SetPageSize(joinRd.GetPageSizeWithRotation(joinPageNum));
// 改ページ
joinDc.NewPage();
// ページ取得
PdfImportedPage joinPage = joinWr.GetImportedPage(joinRd, joinPageNum);
// ページ結合(90,180,270度の回転に対応)
if (pageRotation == 90)
joinPcb.AddTemplate(joinPage, 0, -1, 1, 0, 0, joinRd.GetPageSizeWithRotation(joinPageNum).Height);
else if (pageRotation == 180)
joinPcb.AddTemplate(joinPage, -1, 0, 0, -1, joinRd.GetPageSizeWithRotation(joinPageNum).Width, joinRd.GetPageSizeWithRotation(joinPageNum).Height);
else if (pageRotation == 270)
joinPcb.AddTemplate(joinPage, 0, 1, -1, 0, joinRd.GetPageSizeWithRotation(joinPageNum).Width, 0);
else
joinPcb.AddTemplate(joinPage, 1, 0, 0, 1, 0, 0);
}
}
// 結合先PDFクローズ
joinDc.Close();
}
}
これで回転向きが変わらずにPDFの結合が完了します。