ネットで探しても、あるのか無いのか。作ってみました。
あくまで基本的には、という温かい目で見てください。
簡単そうでなかなか・・・
とりあえず、ASCIIコード、つまり半角英文字と数字・記号が利用できる程度のもので、且つ"ABC"を'AAA'に置換する、という程度のものです。
PDFは漢字を表示できる半角英数字で記述しています。しかも、SJIS・UTF8は指定によりPDF文書ごとに・・・となっているようです。
サーチそのものはCONTENTSの中に出現する文字列をbyte配列の状態で比較しています。
ただ、制御関係の半角英数字が混じっている長いbyte配列なので、制御系とマッチしてしまわないように5文字以上の長めの単語で使ってください。
ここから、制御の文字列ではない状態のケースのみで、マッチするか?という処理をする。というように改造していく感じだと思います。
/// <summary>指定のPDFに、指定の文字列があれば、指定のbyte(初期値は半角SP)で埋めます。</summary>staticprivateboolreplace_PDF_textCONTENTS_proc(stringin_in_filepath,stringin_out_filepath,stringin_moto_text,bytein_埋めるbyte,intin_replace_count=0){if(File.Exists(in_in_filepath)==false)returnfalse;byte[]tmp_sarch_bytes=System.Text.Encoding.UTF8.GetBytes(in_moto_text);PdfReaderreader=newPdfReader(in_in_filepath);for(inti番=1;i番<=reader.NumberOfPages;i番++){PdfDictionarydict=reader.GetPageN(i番);PdfObjectobject2=dict.GetDirectObject(PdfName.CONTENTS);if(object2isPRStream){PRStreamstream=(PRStream)object2;byte[]data=PdfReader.GetStreamBytes(stream);intmatch_count=0;for(inti=0;i<data.Length-tmp_sarch_bytes.Length;i++){bytetype_by=data[i];Func<bool>get_match=()=>{for(intp=0;p<tmp_sarch_bytes.Length;p++){if(data[i+p]!=tmp_sarch_bytes[p])returnfalse;}returntrue;};boolis_match=get_match();if(is_match==false)continue;//// 合致したケースmatch_count++;for(intp=0;p<tmp_sarch_bytes.Length;p++){data[i+p]=in_埋めるbyte;}if(in_replace_count!=0&&match_count==in_replace_count)// 置換の回数指定があれば、その回数の置換で終了します。break;}stream.SetData(data);}}try{PdfStamperstamper=newPdfStamper(reader,newFileStream(in_out_filepath,FileMode.Create));stamper.Close();reader.Close();}catch(Exceptionex){}finally{reader.Close();}returntrue;}
以下のは、異なる長さに置換できるのですが、置換後を""としたところ問題がありました。
WindowsのPDFビュワーでは問題なく表示できます。
ですが、PDFダイレクト対応プリンタ(Ricoh MPC5503)ではエラーで印刷できませんでした。
上の"ABC"を"AAA"にする、置き換え型では大丈夫でした。
文字列が無い、というのが厳密なPDF仕様ではアウトなのかもしれません・・・
staticprivateboolreplace_PDF_textCONTENTS_proc(stringin_in_filepath,stringin_out_filepath,stringin_moto_text,stringin_new_text){if(File.Exists(in_in_filepath)==false)returnfalse;byte[]new_bytes=System.Text.Encoding.UTF8.GetBytes(in_new_text);byte[]tmp_sarch_bytes=System.Text.Encoding.UTF8.GetBytes(in_moto_text);PdfReaderreader=newPdfReader(in_in_filepath);for(intpage番号=1;page番号<=reader.NumberOfPages;page番号++)// このpage番号は1オリジンです{PdfDictionarydict=reader.GetPageN(page番号);PdfObjectobject2=dict.GetDirectObject(PdfName.CONTENTS);if(object2isPRStream){PRStreamstream=(PRStream)object2;byte[]data=PdfReader.GetStreamBytes(stream);List<byte>new_data=newList<byte>();//// 制御の文字列(オペレータ)は以下に詳しく書かれています。// http://www.kobu.com/docs/pdf/pdfxhand.htmstringdebug_text_UTF8=System.Text.Encoding.UTF8.GetString(data);stringdebug_text_Unicode=System.Text.Encoding.Unicode.GetString(data);intmatch_count=0;for(inti=0;i<data.Length-tmp_sarch_bytes.Length;i++){bytetype_by=data[i];chartype_c=(char)type_by;Func<bool>get_match=()=>{for(intp=0;p<tmp_sarch_bytes.Length;p++){if(data[i+p]!=tmp_sarch_bytes[p])returnfalse;}returntrue;};boolis_match=get_match();if(is_match==false){new_data.Add(data[i]);continue;}//// 合致したケースmatch_count++;new_data.AddRange(new_bytes);i+=tmp_sarch_bytes.Length;}//byte[] set_data = ;stream.SetData(new_data.ToArray());}}try{PdfStamperstamper=newPdfStamper(reader,newFileStream(in_out_filepath,FileMode.Create));stamper.Close();reader.Close();}catch(Exceptionex){}reader.Close();returntrue;}