/* Antenna House PDF Tool API V8.0 .NET Interface sample program 概要:テキスト検索して下線、波線、取り消し線注釈 Copyright 2025- Antenna House, Inc. */ using PdfTkNet; using System; using System.Xml; namespace SearchTextAndAppendAnnot { class Program { static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("usage: SearchTextAndAppendAnnot.exe in-pdf-file out-pdf-file keyword"); return; } try { using (PtlParamInput inputFile = new PtlParamInput(args[0])) using (PtlParamOutput outputFile = new PtlParamOutput(args[1])) using (PtlPDFDocument doc = new PtlPDFDocument()) { // PDFファイルをロードします。 doc.load(inputFile); // ページコンテナの取得 using (PtlPages pages = doc.getPages()) using (PtlParamSearchText paramSearchText = new PtlParamSearchText()) // 検索の為のパラメータ using (PtlColorDeviceRGB colorRed = new PtlColorDeviceRGB(1.0f, 0.0f, 0.0f)) { // ページコンテナが空かどうか if (pages.isEmpty()) { Console.WriteLine("ページコンテナが空"); return; } // 検索設定 paramSearchText.appendText(args[2]); // 検索実行して検索結果コンテナ取得 using (PtlSearchTextResults results = doc.searchText(paramSearchText)) { int numResults = results.getCount(); for (int i = 0; i < numResults; ++i) { // 検索結果取得 using (PtlSearchTextResult result = results.get(i)) { // 検索に使用したキーワード String keyword = result.getKeyword(); // ヒットしたページ番号 int pageNumber = result.getPageNumber(); using (PtlPage page = pages.get(pageNumber)) using (PtlAnnots annots = page.getAnnots()) // 検索結果詳細コンテナ取得 using (PtlSearchTextResultDetails details = result.getResultDetails()) { int numDetails = details.getCount(); for (int j = 0; j < numDetails; ++j) { // 検索結果詳細取得 using (PtlSearchTextResultDetail resultDetail = details.get(j)) using (PtlAnnotHighlight annot = new PtlAnnotHighlight()) using (PtlQuadPoints quads = annot.getQuadPoints()) // 検索に使用したキーワードの部分文字列を囲むQuadPoint using (PtlQuadPoint quad = resultDetail.getQuadPoint()) { // 検索に使用したキーワードの部分文字列 String keywordD = resultDetail.getKeyword(); // 検索に使用したキーワードの部分文字列が縦書きか bool verticalWriting = resultDetail.isVerticalWriting(); //注釈の追加 switch (i % 3) { case 0: //波状下線注釈 addAnnotSquiggly(annots, quad, verticalWriting); break; case 1: //取り消し線注釈 addAnnotStrikeOut(annots, quad, verticalWriting); break; case 2: //下線注釈 addAnnotUnderline(annots, quad, verticalWriting); break; } //// 文字列にハイライト注釈を付ける //using (PtlAnnotHighlight annot = new PtlAnnotHighlight()) //using (PtlQuadPoints quads = annot.getQuadPoints()) //{ // // 検索に使用したキーワードの部分文字列を囲むQuadPoint // using (PtlQuadPoint quad = resultDetail.getQuadPoint()) // { // quads.append(quad); // } // // 検索に使用したキーワードの部分文字列が縦書きか // bool verticalWriting = resultDetail.isVerticalWriting(); // annot.setVerticalDirection(verticalWriting); // annot.setColor(colorRed); // annot.setMarkUpCA(0.5f); // annots.append(annot); //} } } } } } } } // ファイルに保存します。 doc.save(outputFile); } } catch (PtlException pex) { Console.WriteLine(pex.getErrorCode() + " : " + pex.getErrorMessageJP()); pex.Dispose(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine("-- 完了 --"); } } static void addAnnotSquiggly(PtlAnnots annots, PtlQuadPoint quadPoint, bool verticalWriting) { using (PtlAnnotSquiggly annotSquiggly = new PtlAnnotSquiggly()) //PDFの波状下線注釈 using (PtlAnnotPopup annotpopup = new PtlAnnotPopup()) { //矩形座標を設定 座標の単位はmmで原点(0,0)は左下 using (PtlQuadPoints points = annotSquiggly.getQuadPoints()) { points.append(quadPoint); } // 検索に使用したキーワードの部分文字列が縦書きか annotSquiggly.setVerticalDirection(verticalWriting); //内容を設定(注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明) annotSquiggly.setTextContents("波状下線注釈サンプル"); //日時の設定(2025/2/1 0:0:0) using (PtlDate date = new PtlDate(2025, 2, 1, 0, 0, 0)) { annotSquiggly.setDate(date); } //注釈フラグを設定(論理和) FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */ annotSquiggly.setAnnotFlags(PtlAnnotText.ANNOT_FLAGS.FLAG_NOROTATE); //色を設定 setColor(const PtlColorDeviceRGB& color); using (PtlColorDeviceRGB color = new PtlColorDeviceRGB(1.0f, 0.0f, 0.0f)) { annotSquiggly.setColor(color); } //境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */ annotSquiggly.setBorderStyle(PtlAnnotText.BORDER_STYLE.BORDER_SOLID); //境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */ annotSquiggly.setBorderWidth(PtlAnnotText.BORDER_LINE_WIDTH.BORDER_WIDTH_THIN); //注釈の追加 annots.append(annotSquiggly); } } static void addAnnotStrikeOut(PtlAnnots annots, PtlQuadPoint quadPoint, bool verticalWriting) { using (PtlAnnotStrikeOut annotStrikeOut = new PtlAnnotStrikeOut()) //PDFの消し線注釈 using (PtlAnnotPopup annotpopup = new PtlAnnotPopup()) { //矩形座標を設定 座標の単位はmmで原点(0,0)は左下 using (PtlQuadPoints points = annotStrikeOut.getQuadPoints()) { points.append(quadPoint); } // 検索に使用したキーワードの部分文字列が縦書きか annotStrikeOut.setVerticalDirection(verticalWriting); //内容を設定(注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明) annotStrikeOut.setTextContents("取り消し線注釈サンプル"); //日時の設定(2025/2/1 0:0:0) using (PtlDate date = new PtlDate(2025, 2, 1, 0, 0, 0)) { annotStrikeOut.setDate(date); } //注釈フラグを設定(論理和) FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */ annotStrikeOut.setAnnotFlags(PtlAnnotText.ANNOT_FLAGS.FLAG_NOROTATE); //色を設定 setColor(const PtlColorDeviceRGB& color); using (PtlColorDeviceRGB color = new PtlColorDeviceRGB(1.0f, 0.0f, 0.0f)) { annotStrikeOut.setColor(color); } //境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */ annotStrikeOut.setBorderStyle(PtlAnnotText.BORDER_STYLE.BORDER_SOLID); //境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */ annotStrikeOut.setBorderWidth(PtlAnnotText.BORDER_LINE_WIDTH.BORDER_WIDTH_THIN); //注釈の追加 annots.append(annotStrikeOut); } } static void addAnnotUnderline(PtlAnnots annots, PtlQuadPoint quadPoint, bool verticalWriting) { using (PtlAnnotUnderline annotUnderLine = new PtlAnnotUnderline()) //PDFの下線注釈 using (PtlAnnotPopup annotpopup = new PtlAnnotPopup()) { //矩形座標を設定 座標の単位はmmで原点(0,0)は左下 using (PtlQuadPoints points = annotUnderLine.getQuadPoints()) { points.append(quadPoint); } // 検索に使用したキーワードの部分文字列が縦書きか annotUnderLine.setVerticalDirection(verticalWriting); //内容を設定(注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明) annotUnderLine.setTextContents("下線注釈サンプル"); //日時の設定(2025/2/1 0:0:0) using (PtlDate date = new PtlDate(2025, 2, 1, 0, 0, 0)) { annotUnderLine.setDate(date); } //注釈フラグを設定(論理和) FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */ annotUnderLine.setAnnotFlags(PtlAnnotText.ANNOT_FLAGS.FLAG_NOROTATE); //色を設定 setColor(const PtlColorDeviceRGB& color); using (PtlColorDeviceRGB color = new PtlColorDeviceRGB(1.0f, 0.0f, 0.0f)) { annotUnderLine.setColor(color); } //境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */ annotUnderLine.setBorderStyle(PtlAnnotText.BORDER_STYLE.BORDER_SOLID); //境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */ annotUnderLine.setBorderWidth(PtlAnnotText.BORDER_LINE_WIDTH.BORDER_WIDTH_THIN); //注釈の追加 annots.append(annotUnderLine); } } } }