微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何调整具有宽iText7 PdfTable的文档的大小,该文档也是一个大表,并且具有取消支持,而无需蛮力执行两个循环?

如何解决如何调整具有宽iText7 PdfTable的文档的大小,该文档也是一个大表,并且具有取消支持,而无需蛮力执行两个循环?

我想将大量数据,成千上万条记录放入PDF中,但具有取消支持。说,用户单击按钮以生成PDF,但改变主意并刷新页面,或导航离开。 ASP.NET Core为控制器提供了CancellationToken支持(是的),但是出于某些愚蠢的原因,iText7没有公开可以利用此功能的Async方法。让我们来看下面的示例:

PdfDocument pdfDoc = new PdfDocument(new PdfWriter(memoryStream));
Document doc = new Document(pdfDoc);

// The second argument determines 'large table' functionality is used
// It defines whether parts of the table will be written before all data is added.
Table table = new Table(UnitValue.CreatePercentArray(5),true);

for (int i = 0; i < 5; i++)
{
    table.AddHeaderCell(new Cell().SetKeepTogether(true).Add(new Paragraph("Header " + i)));
}

// For the "large tables" they shall be added to the document before its child elements are populated
doc.Add(table);

for (int i = 0; i < 150000; i++)
{
    if (i % 500 == 0)
    {
// Flushes the current content,e.g. places it on the document.
        table.Flush();
        if (cancellationToken.IsCancellationRequested)
        {
           doc.Close();
           pdfDoc.Close();
           memoryStream.Close();
           await _stream.disposeAsync();
           cancellationToken.ThrowIfCancellationRequested();
        }
    }
    table.AddCell(new Cell().SetKeepTogether(true).Add(new Paragraph("Test " + i)
        .SetMargins(0,0)));
}

// Flushes the rest of the content and indicates that no more content will be added to the table
table.Complete();
doc.Close();
return memoryStream.ToArray();

代码为pdf生成(每100行)添加了取消支持,因为它使用iText7的Large Table模式。 这样很好,但我的桌子可能太宽,无法容纳在标准的A4页面上,但是我不知道这一点,只有在以下事实之后:

IRenderer tableRenderer = _table.CreateRendererSubTree().SetParent(_doc.GetRenderer());
MinMaxWidth minMaxWidth = ((TableRenderer) tableRenderer).GetMinMaxWidth();

float a4Width = PageSize.A4.GetWidth();
float width = minMaxWidth.GetMinWidth() < a4Width ? a4Width : minMaxWidth.GetMinWidth();
doc = new iText.Layout.Document(pdfDoc,new PageSize(width + leftMargin * 2,heightTotal + topMargin * 2),false);
// This cannot be cancelled whatsoever and also blocks the thread.
doc.Add(table);

我必须渲染表格以获取表格的宽度。但据我所知,我无法修改现有文档的宽度,因此必须创建一个新文档。然后将表也添加到该表中。 现在我知道这两个代码甚至不兼容,因为将表添加到新文档中不会产生任何结果,因为该表是专门针对第一个文档设置的Flush()

所以我的第一个问题是,如何在不再次遍历数据或创建两个单独的表来存储数据的情况下完成这项工作?

但是可以说它是兼容的。然后,这将导致无法取消的内存密集型任务,即向新文档中添加3万行表。这对我来说是不良行为。

所以我的问题是,有没有一种方法可以“异步地”将表呈现给内存中的文档,同时保留取消支持,以免不必要地负担服务器的负担,还可以确保该文档将足够宽的桌子适合吗? 还是有一种方法可以调整当前文档的大小并使其更宽,但是保留所有其他特征? (表格已经过渲染,超出了右边距并且消失了,所以我知道它在那里,只是页面大小不够宽而无法显示。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。