2024年12月26日木曜日

PDFsharpを使って複数のpdfを結合する

 

複数のpdfを結合して1つのpdfにしたいっていうこと、たまにあるよね。PDFsharpっていうdotnet libraryで実現できるらしいので軽い気持ちでやってみる。


"pdfsharp 結合 dotnet"でググるとまぁ結構出てくる。とりあえず、この辺(https://qiita.com/benjamin1gou/items/718e6dbbe8e831529737)を参考にする。
で、コマンドラインで入力ファイルと出力ファイルを引数にとって実行するってしたいんだけど、コマンドライン引数の解析ってめんどいんよね。で、System.CommandLine パッケージってのがあるらしいんだけど、、、prereleaseってなっていて、、、あまり参考情報がないので、ギブアップ。拙い感じで自力で実装することにする。
では、
mkdir pdf_connector
cd pdf_connector
dotnet new console
dotnet add package pdfsharp
ってやって、あとは好きな感じでProgram.csをいじる。VSCode使うもよし、別のエディタでもよし。
で、こういうコード
  1. using PdfSharp.Pdf;
  2. using PdfSharp.Pdf.IO;
  3. public class pdf_connector{
  4.     static void Main(string[] args)
  5.     {
  6.         int opos=0;
  7.         int skip=0;
  8.         int n=0;
  9.         var list_ifiles=new List<string>();
  10.         string ofile="";
  11.         //Console.WriteLine(args.Length);
  12.         foreach(string sarg in args){
  13.             if(opos==1){
  14.                 ofile=sarg;
  15.                 skip=1;
  16.             }
  17.             if(sarg=="-o"){
  18.                 opos=1;
  19.             }else{
  20.                 opos=0;
  21.                 if(skip==0){
  22.                     list_ifiles.Add(sarg);
  23.                     n=n+1;
  24.                 }
  25.             }
  26.             //Console.WriteLine(sarg);
  27.         }
  28.         string[] ifiles=list_ifiles.ToArray();
  29.         Console.WriteLine("Input file(s):");
  30.         foreach(string ifile in ifiles){
  31.             Console.WriteLine(ifile);
  32.         }
  33.         Console.WriteLine("Output file:");
  34.         Console.WriteLine(ofile);
  35.         MergePdfFiles(ifiles,ofile);
  36.     }
  37.     private static void MergePdfFiles(string[] sourceFilenames, string destinationFilename)
  38.     {
  39.         using (PdfDocument document = new PdfDocument()){
  40.             foreach (string filename in sourceFilenames){
  41.                 using (PdfDocument inputDocument = PdfReader.Open(filename, PdfDocumentOpenMode.Import)){
  42.                     foreach (PdfPage page in inputDocument.Pages){
  43.                         document.AddPage(page);
  44.                     }
  45.                 }
  46.             }
  47.             document.Save(destinationFilename);
  48.         }
  49.     }
  50. }
で、適当にpdfを作って、プロジェクトのルートフォルダに置いておく。で、
dotnet run -- aa.pdf bb.pdf cc.pdf -o kk.pdf
("--"以降の記述が実行ファイルの引数になるんだよー)
ってすると、kk.pdfが出来上がっていて、ちゃんと結合されているってのがわかる(<--すまんエビデンスは省略)。用紙サイズ違いもお構いなしにつなげてくれるのでなかなかよい。たったこれだけの作業で、たった50行のプログラムで、できちゃうんだから、みんなコンピューター言語やればいいのに、、、ってのと、やっぱり「コンソールアプリ」だよなー。大したことしないアプリだとGUIはムダムダムダ。

「これがUNIXの哲学である。
一つのことを行い、またそれをうまくやるプログラムを書け。
協調して動くプログラムを書け。
標準入出力(テキスト・ストリーム)を扱うプログラムを書け。標準入出力は普遍的インターフェースなのだ。」
「Worse is better」

あ、実行ファイルは、
dotnet build --configuration Release
ってすると、プロジェクトフォルダの下のどこかにできる。exeだけで使えるのか、dllも要るのかはまぁ試してみりゃわかるっしょ、、、
あ、PDFsharp以外にもpdfを扱えるdotnet libraryがあるっぽいけど、PDFsharpはMITライセンスなのが素晴らしい。

0 件のコメント:

コメントを投稿