亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無法使用 MemoryStream 合并 2 個 PDF

無法使用 MemoryStream 合并 2 個 PDF

C#
月關寶盒 2023-09-16 20:10:47
我有一個 c# 類,它接受 HTML 并使用 wkhtmltopdf 將其轉換為 PDF。正如您將在下面看到的,我生成了 3 個 PDF - 橫向、縱向以及兩者的組合。該properties對象包含字符串形式的 html 以及橫向/縱向的參數。System.IO.MemoryStream PDF = new WkHtmlToPdfConverter().GetPdfStream(properties);System.IO.FileStream file = new System.IO.FileStream("abc_landscape.pdf", System.IO.FileMode.Create);PDF.Position = 0;properties.IsHorizontalOrientation = false;System.IO.MemoryStream PDF_portrait = new WkHtmlToPdfConverter().GetPdfStream(properties);System.IO.FileStream file_portrait = new System.IO.FileStream("abc_portrait.pdf", System.IO.FileMode.Create);PDF_portrait.Position = 0;System.IO.MemoryStream finalStream = new System.IO.MemoryStream();PDF.CopyTo(finalStream);PDF_portrait.CopyTo(finalStream);System.IO.FileStream file_combined = new System.IO.FileStream("abc_combined.pdf", System.IO.FileMode.Create);try{    PDF.WriteTo(file);    PDF.Flush();    PDF_portrait.WriteTo(file_portrait);    PDF_portrait.Flush();    finalStream.WriteTo(file_combined);    finalStream.Flush();}catch (Exception){    throw;}finally{    PDF.Close();    file.Close();    PDF_portrait.Close();    file_portrait.Close();    finalStream.Close();    file_combined.Close();}PDF“abc_landscape.pdf”和“abc_portrait.pdf”按預期正確生成,但當我嘗試將兩者合并到第三個 pdf (abc_combined.pdf) 中時,操作失敗。我用來MemoryStream執行合并,在調試時,我可以看到finalStream.length等于前兩個 PDF 的總和。但當我嘗試打開 PDF 時,我只看到兩個 PDF 中的 1 個的內容。下圖也可以看到同樣的情況:此外,當我嘗試關閉“abc_combined.pdf”時,系統會提示我保存它,而其他 2 個 PDF 則不會出現這種情況。以下是我已經嘗試過的一些方法,但沒有效果:將 CopyTo() 更改為 WriteTo()將相同的 PDF(橫向或縱向)與其自身合并如果需要,下面是該GetPdfStream()方法的詳細說明。var htmlStream = new MemoryStream();var writer = new StreamWriter(htmlStream);writer.Write(htmlString);writer.Flush();htmlStream.Position = 0;return htmlStream;Process process = Process.Start(psi);process.EnableRaisingEvents = true;
查看完整描述

4 回答

?
函數式編程

TA貢獻1807條經驗 獲得超9個贊

如果不使用第 3 方庫,用 C# 或任何其他語言合并 pdf 并不簡單。

我假設您不使用庫的要求是大多數免費庫、nuget 包都有限制或/并且商業用途需要花錢。

我做了研究,找到了一個名為PdfClown的開源庫,帶有nuget包,它也適用于 Java。它是免費的,沒有限制(如果您愿意,請捐贈)。該庫有很多功能。您可以將 2 個或多個文檔合并為一個文檔。

我提供了一個示例,該示例采用一個包含多個 pdf 文件的文件夾,將其合并并將其保存到同一個或另一個文件夾中。也可以使用 MemoryStream,但我認為在這種情況下沒有必要。

代碼是自我解釋的,這里的關鍵點是使用SerializationModeEnum.Incremental

public static void MergePdf(string srcPath, string destFile)

{

? ? var list = Directory.GetFiles(Path.GetFullPath(srcPath));

? ? if (string.IsNullOrWhiteSpace(srcPath) || string.IsNullOrWhiteSpace(destFile) || list.Length <= 1)

? ? ? ? return;

? ? var files = list.Select(File.ReadAllBytes).ToList();

? ? using (var dest = new org.pdfclown.files.File(new org.pdfclown.bytes.Buffer(files[0])))

? ? {

? ? ? ? var document = dest.Document;

? ? ? ? var builder = new org.pdfclown.tools.PageManager(document);

? ? ? ? foreach (var file in files.Skip(1))

? ? ? ? {

? ? ? ? ? ? using (var src = new org.pdfclown.files.File(new org.pdfclown.bytes.Buffer(file)))

? ? ? ? ? ? { builder.Add(src.Document); }

? ? ? ? }


? ? ? ? dest.Save(destFile, SerializationModeEnum.Incremental);

? ? }

}

測試一下


var srcPath = @"C:\temp\pdf\input";

var destFile = @"c:\temp\pdf\output\merged.pdf";

MergePdf(srcPath, destFile);

輸入示例

PDF 文檔 A 和 PDF 文檔 B

https://img1.sycdn.imooc.com/65059bab0001ed5a06360362.jpg

輸出示例


https://img3.sycdn.imooc.com/65059bb70001dfb603910635.jpg

查看完整回答
反對 回復 2023-09-16
?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

這個答案有用:


? ? ? using (PdfDocument one = PdfReader.Open("pdf 1.pdf", PdfDocumentOpenMode.Import))

? ? ? ? using (PdfDocument two = PdfReader.Open("pdf 2.pdf", PdfDocumentOpenMode.Import))

? ? ? ? using (PdfDocument outPdf = new PdfDocument())

? ? ? ? {

? ? ? ? ? ? CopyPages(one, outPdf);

? ? ? ? ? ? CopyPages(two, outPdf);


? ? ? ? ? ? outPdf.Save("file1and2.pdf");

? ? ? ? }


? ? ? ? void CopyPages(PdfDocument from, PdfDocument to)

? ? ? ? {

? ? ? ? ? ? for (int i = 0; i < from.PageCount; i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? to.AddPage(from.Pages[i]);

? ? ? ? ? ? }

? ? ? ? }


查看完整回答
反對 回復 2023-09-16
?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

PDF 的工作原理并不完全是這樣。PDF 是特定格式的結構化文件。您不能只是將一個字節附加到另一個字節并期望結果是有效的文檔。

您將必須使用一個能夠理解格式并可以為您執行操作的庫,或者開發您自己的解決方案。


查看完整回答
反對 回復 2023-09-16
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

PDF 文件不僅僅是文本和圖像。在幕后有一個嚴格的文件格式來描述 PDF 版本、文件中包含的對象以及在哪里可以找到它們等內容。

為了合并 2 個 PDF,您需要操作流。

首先,您需要僅保留其中一個文件的標頭。這非常簡單,因為它只是第一行。

然后你可以寫第一頁的正文,然后是第二頁。

現在最困難的部分,也可能是說服您使用庫的部分,是您必須重新構建外部參照表。外部參照表是一個交叉引用表,它描述了文檔的內容,更重要的是在哪里可以找到每個元素。您必須計算第二頁的字節偏移量,將其外部參照表中的所有元素移動那么多,然后將其外部參照表添加到第一頁。您還需要確保在外部參照表中為分頁符創建對象。

完成后,您需要重新構建文檔預告片,它告訴應用程序文檔的各個部分的位置。

查看完整回答
反對 回復 2023-09-16
  • 4 回答
  • 0 關注
  • 193 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號