gpt4 book ai didi

c# - 使用 itextsharp 根据大小将 pdf 拆分为更小的 pdf

转载 作者:行者123 更新时间:2023-11-30 12:33:36 25 4
gpt4 key购买 nike

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

这是我继承的代码,我觉得必须有一种更有效的方法来做到这一点,只需要一个方法和更少的对象实例化。

我们使用下面的代码来调用这些方法:

        List<int> splitPoints = null;
List<byte[]> documents = null;

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

方法:

    private List<int> GetPDFSplitPoints(IClaimDocument currentDocument, int maxSize)
{
List<int> splitPoints = new List<int>();
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 < currentDocument.Pages; i++)
{
int currentPage = currentDocument.Pages - (pagesRemaining - 1);

if (pagesRemaining == 0)
{
//The whole document has bee traversed
break;
}

page = copy.GetImportedPage(reader, currentPage);
copy.AddPage(page);

//If the current collection of pages exceeds the maximum size, we save off the index and start again
if (copy.CurrentDocumentSize > 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<byte[]> SplitPDF(IClaimDocument currentDocument, int maxSize, List<int> splitPoints)
{
var documents = new List<byte[]>();
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,不一定能解决大小问题。

更新:

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

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

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

最佳答案

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

关于c# - 使用 itextsharp 根据大小将 pdf 拆分为更小的 pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9024839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com