先處理數位簽名檔合併到PDF中。
參考了 [itextsharp][006]加入image到pdf(add image to pdf) 作者:kevinya
蠻完整的寫出了三種方式加入。
這次需求只需要固定在左下角固定位置簽入簽名檔,所以我們採用絕對位置來設計。
/// <summary>
/// 將PDF檔與簽名檔合併
/// </summary>
/// <param name="outPdfPath">PDF輸出的檔案路徑</param>
/// <param name="oriPdfFullPath">原始PDF檔案完整路徑</param>
/// <param name="signFileFullPath">簽名檔檔案完整路徑</param>
/// <param name="outPdfFileName">合併後輸出的檔案名稱</param>
private static void MergeSign(string outPdfPath, string oriPdfFullPath, string signFileFullPath,
out string outPdfFileName)
{
outPdfFileName = GetUniqueFileName(".pdf", outPdfPath);
using (var reader = new PdfReader(oriPdfFullPath))
using (var stamper = new PdfStamper(reader,
new FileStream(Path.Combine(outPdfPath, outPdfFileName), FileMode.Create)))
{
var pageCount = reader.NumberOfPages;
for (var i = 1; i <= pageCount; i++)
{
var content = stamper.GetOverContent(i);
var image = iTextSharp.text.Image.GetInstance(signFileFullPath);
image.ScaleAbsolute(100, 100);
image.SetAbsolutePosition(70, 10);
content.AddImage(image);
}
}
}
GetUniqueFileName 就是一個取得檔名的Function,這邊就不贅述。
這次需求是一份PDF可能是N頁的簽收單,所以,我們需要跑一個迴圈來處理。
再來,我們處理PDF匯出圖檔,這部分說真的卡比較久,沒想到參考資源一直找錯方向。
一開始因為找的解決方案,都會要求要先安裝東西在主機上,這不是我想使用的方案。
當時就有看到 Ghostscript 但沒採用。
試用了 NReco.PdfRenderer ,官方Demo只要短短4行就解決了。
var pdfFile = "Sample1.pdf";
var pdfToImg = new NReco.PdfRenderer.PdfToImageConverter();
pdfToImg.ScaleTo = 200; // fit 200x200 box
pdfToImg.GenerateImage( pdfFile, 1, ImageFormat.Jpeg, "Sample1.jpg" );
原本卡要刷下去了,但又回頭看了一下Gostscript。
NuGet搜尋Gostscript,跳出來了 Ghostscript.NET
直覺這東西肯定可以打救我。
果然,符合我想要的,雖然他依賴著Gostscript,但是主機不一定要先安裝。
只需要擁有Dll檔。
private static GhostscriptVersionInfo GetGhostscriptVersionInfo()
{
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var vesion = new GhostscriptVersionInfo(new Version(0, 0, 0), path + @"\gsdll32.dll", string.Empty,
GhostscriptLicense.GPL);
return vesion;
}
之後透過 GhostscriptRasterizer 來達成。
private static void PdfToImage(string outPdfTempImagePath, string outPdfImagePath, string file,
out string outImageFileName)
{
var tempFiles = new List<string>();
using (var rasterizer = new GhostscriptRasterizer())
{
rasterizer.Open(file, GhostScriptVersion, false);
for (var i = 1; i <= rasterizer.PageCount; i++)
{
var fileName = Path.Combine(outPdfTempImagePath, GetUniqueFileName(".png", outPdfTempImagePath));
tempFiles.Add(fileName);
var img = rasterizer.GetPage(DesiredXDpi, DesiredYDpi, i);
if (i == 1)
img.Save(fileName, ImageFormat.Png);
else
{
img.RotateFlip(RotateFlipType.Rotate90FlipNone);
img.Save(fileName, ImageFormat.Png);
}
}
rasterizer.Close();
}
outImageFileName = GetUniqueFileName(".png", outPdfImagePath);
MergeImages(tempFiles).Save(Path.Combine(outPdfImagePath, outImageFileName));
}
這邊也是一頁一頁的匯出圖檔,又很特別轉圖檔第二張之後會變成橫向,所以,我們還要再轉個角度。(這部分還沒驗證是否為來源PDF的問題)。
一頁一頁匯出後,我在自己做合併的動作。
完整程式放在:GitHub