使用itextsharp根据大小将pdf拆分为较小的pdf

所以我们有一些非常低效的代码,根据允许的最大大小将pdf分成更小的块。 阿卡。 如果最大大小为10megs,则将跳过8兆字节文件,而将根据页数拆分16兆字节文件。

这是我inheritance的代码,并且感觉必须有一种更有效的方法来执行此操作,只需要一个方法和较少的对象实例化。

我们使用以下代码来调用方法:

List splitPoints = null; List documents = null; splitPoints = this.GetPDFSplitPoints(currentDocument, maxSize); documents = this.SplitPDF(currentDocument, maxSize, splitPoints); 

方法:

  private List GetPDFSplitPoints(IClaimDocument currentDocument, int maxSize) { List splitPoints = new List(); PdfReader reader = null; Document document = null; int pagesRemaining = currentDocument.Pages; while (pagesRemaining > 0) { reader = new PdfReader(currentDocument.Data); document = new Document(reader.GetPageSizeWithRotation(1)); using (MemoryStream ms = new MemoryStream()) { PdfCopy copy = new PdfCopy(document, ms); PdfImportedPage page = null; document.Open(); //Add pages until we run out from the original for (int i = 0; i  maxSize) { if (i == 0) { //One page is greater than the maximum size throw new Exception("one page is greater than the maximum size and cannot be processed"); } //We have gone one page too far, save this split index splitPoints.Add(currentDocument.Pages - (pagesRemaining - 1)); break; } else { pagesRemaining--; } } page = null; document.Close(); document.Dispose(); copy.Close(); copy.Dispose(); copy = null; } } if (reader != null) { reader.Close(); reader = null; } document = null; return splitPoints; } private List SplitPDF(IClaimDocument currentDocument, int maxSize, List splitPoints) { var documents = new List(); PdfReader reader = null; Document document = null; MemoryStream fs = null; int pagesRemaining = currentDocument.Pages; while (pagesRemaining > 0) { reader = new PdfReader(currentDocument.Data); document = new Document(reader.GetPageSizeWithRotation(1)); fs = new MemoryStream(); PdfCopy copy = new PdfCopy(document, fs); PdfImportedPage page = null; document.Open(); //Add pages until we run out from the original for (int i = 0; i <= currentDocument.Pages; i++) { int currentPage = currentDocument.Pages - (pagesRemaining - 1); if (pagesRemaining == 0) { //We have traversed all pages //The call to copy.Close() MUST come before using fs.ToArray() because copy.Close() finalizes the document fs.Flush(); copy.Close(); documents.Add(fs.ToArray()); document.Close(); fs.Dispose(); break; } page = copy.GetImportedPage(reader, currentPage); copy.AddPage(page); pagesRemaining--; if (splitPoints.Contains(currentPage + 1) == true) { //Need to start a new document //The call to copy.Close() MUST come before using fs.ToArray() because copy.Close() finalizes the document fs.Flush(); copy.Close(); documents.Add(fs.ToArray()); document.Close(); fs.Dispose(); break; } } copy = null; page = null; fs.Dispose(); } if (reader != null) { reader.Close(); reader = null; } if (document != null) { document.Close(); document.Dispose(); document = null; } if (fs != null) { fs.Close(); fs.Dispose(); fs = null; } return documents; } 

据我所知,我能看到的唯一在线代码是VB,并不一定解决大小问题。

更新

我们遇到了OutofMemoryexception,我认为这是大对象堆的问题。 因此,一个想法是减少代码占用空间,这可能会减少堆上的大对象数量。

基本上,这是循环的一部分,遍历任意数量的PDF,然后拆分它们并将它们存储在数据库中。 现在,我们不得不改变方法,一次完成所有这些(最后一次运行是各种大小的97 pdf),每5分钟通过系统运行5个pdf。 这不是理想的,当我们将工具增加到更多客户端时,它不会很好地扩展。

(我们正在处理50 -100 meg pdf,但它们可能更大)。

我也inheritance了这个确切的代码,似乎存在一个重大缺陷。 在GetPDFSplitPoints方法中,它根据maxsize检查复制页面的总大小,以确定在哪个页面拆分文件。
SplitPDF方法中,当它到达发生拆分的页面时,此时的MemoryStream肯定低于允许的最大大小,并且还有一页将使其超出限制。 但是在document.Close(); 执行后, MemoryStream添加了更多内容(在我使用的PDF文件中, MemoryStreamLengthdocument.Close前后的9 MB变为19 MB。 document.Close )。 我的理解是,在Close添加复制页面的所有必要资源。
我猜我必须完全重写这段代码,以确保我不会超过最大尺寸,同时保持原始页面的完整性。