创建表格时如何提高 iText 性能

2024-02-11

嘿,很棒的 Stackoverflow 人

我目前正在评估我们是否应该使用 iText 7.1.9 for Java 还是 C#。 为此,我创建了一个测试用例,其中我编写了一个包含一堆页面的 PDF,每个页面都包含一个大表格(代码如下)。

在 Java 中,创建包含 x 页的 PDF 会产生以下结果:

  • 1 页:0 秒
  • 10 页:1 秒
  • 100 页:5 秒
  • 1000 页:23 秒

这是相当有效的。然而,当我将完全相同的代码移植到 C# .Net 时,我感到非常震惊:

  • 1 页:0 秒
  • 10 页:1 秒
  • 100 页:10 秒
  • 1000 页:96 秒

使用 Java 创建的 PDF 与 C# 创建的 PDF 大小相同,并且文件看起来完全相同。 然而,C# 似乎是线性扩展的,而 Java 则设法优化更大的 PDF。

由于我们更愿意使用 C#,所以问题是:

  1. 这到底是怎么回事?
  2. 我需要做什么才能获得与 Java 大致相同的性能吗?

Java代码:

package pcm;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.io.FileInputStream;
import java.io.IOException;

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
import com.itextpdf.kernel.pdf.PdfOutputIntent;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.PdfViewerPreferences;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.AreaBreakType;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.pdfa.PdfADocument;

public class PcmSimple {    
    public static void main(String[] args) {        
        long startTime, elapsedTime;

        try {           
            for(int i=1; i<=1000; i*=10) {
                startTime = System.nanoTime();
                createPdf("D:\\Pcm Test", i);           
                elapsedTime = System.nanoTime() - startTime;

                System.out.println(String.format("%04d pages: %02d sec", i, NANOSECONDS.toSeconds(elapsedTime)));
            }
        } catch(Exception ex) {
            System.out.println(ex.getMessage() + ": " + ex.getStackTrace());
        }
    }

    private static void createPdf(String path, int numberOfPages) throws IOException {
        PdfFont fontBold = PdfFontFactory.createFont("resources/fonts/OpenSans-Bold.ttf", true);
        PdfFont fontComic = PdfFontFactory.createFont("resources/fonts/comic-sans-ms_[allfont.de].ttf", true);

        // Set up the document.     
        PdfADocument pdfDocument = new PdfADocument(
                new PdfWriter(String.format("%s\\java_%d_pages.pdf", path, numberOfPages)), 
                PdfAConformanceLevel.PDF_A_3B, 
                new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", 
                        new FileInputStream("resources/color/sRGB_CS_profile.icm")));

        pdfDocument.setTagged();
        pdfDocument.getDocumentInfo().setTitle("Reference Document");
        pdfDocument.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
        pdfDocument.getCatalog().setLang(new PdfString("en-US"));

        Document document = new Document(pdfDocument);

        // Add a table to every page.
        for (int i = 0; i < numberOfPages; i++) {
            Table table = new Table(5);
            table.setWidth(UnitValue.createPercentValue(100));

            for (int j = 0; j < 5; j++) {                
                Cell cell = new Cell(2, 1)
                        .add(new Paragraph("Header " + j).setMultipliedLeading(0.5f))
                        .setFont(fontBold)
                        .setFontSize(20)
                        .setBackgroundColor(ColorConstants.CYAN);

                table.addHeaderCell(cell);
            }

            for(int j=0; j<225; j++) {              
                Cell cell = new Cell()
                        .add(new Paragraph("Test " + j).setMultipliedLeading(0.5f))
                        .setFont(fontComic)
                        .setPaddingTop(4.1f);

                table.addCell(cell);
            }

            document.add(table);
            document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        }

        document.close();
    }
}

C# .Net 代码:

using iText.Kernel.Colors;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
using iText.Pdfa;
using System;
using System.IO;

namespace PCM_Performance_Test_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime startTime;
            long elapsedTime;

            try
            {
                for (int i = 1; i <= 1000; i *= 10)
                {
                    startTime = DateTime.Now;
                    CreatePdf("D:\\Pcm Test", i);
                    elapsedTime = (long)(DateTime.Now - startTime).TotalSeconds;

                    Console.WriteLine($"{i:d04} pages: {elapsedTime:d02} sec");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ": " + ex.StackTrace);
            }
            finally
            {
                Console.Read();
            }
        }

        private static void CreatePdf(String path, int numberOfPages)
        {
            PdfFont fontBold = PdfFontFactory.CreateFont("resources/fonts/OpenSans-Bold.ttf", true);
            PdfFont fontComic = PdfFontFactory.CreateFont("resources/fonts/comic-sans-ms_[allfont.de].ttf", true);

            // Set up the document.     
            PdfADocument pdfDocument = new PdfADocument(
                    new PdfWriter($"{path}\\csharp_{numberOfPages}_pages.pdf"),
                    PdfAConformanceLevel.PDF_A_3B,
                    new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1",
                            new FileStream("resources/color/sRGB_CS_profile.icm", FileMode.Open, FileAccess.Read)));

            pdfDocument.SetTagged();
            pdfDocument.GetDocumentInfo().SetTitle("Reference Document");
            pdfDocument.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
            pdfDocument.GetCatalog().SetLang(new PdfString("en-US"));

            Document document = new Document(pdfDocument);

            // Add a table to every page.
            for (int i = 0; i < numberOfPages; i++)
            {
                Table table = new Table(5);
                table.SetWidth(UnitValue.CreatePercentValue(100));

                for (int j = 0; j < 5; j++)
                {
                    Cell cell = new Cell(2, 1)
                            .Add(new Paragraph("Header " + j).SetMultipliedLeading(0.5f))
                            .SetFont(fontBold)
                            .SetFontSize(20)
                            .SetBackgroundColor(ColorConstants.CYAN);

                    table.AddHeaderCell(cell);
                }

                for (int j = 0; j < 225; j++)
                {
                    Cell cell = new Cell()
                            .Add(new Paragraph("Test " + j).SetMultipliedLeading(0.5f))
                            .SetFont(fontComic)
                            .SetPaddingTop(4.1f);

                    table.AddCell(cell);
                }

                document.Add(table);
                document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
            }

            document.Close();
        }
    }
}


这不是你的代码,而是库,我设置了一个测试项目,我能做的最好的就是削减大约 20%,但这并没有接近 java 版本的性能......

  • 0001 页:0.1133129
  • 0010 页:0.9318324
  • 0100 页:8.2051265
  • 1000 页:80.615356

void Main()
{
    DateTime startTime;
    TimeSpan elapsedTime;
    int xy = 1000;
    try
    {
        for (int i = 1; i <= xy; i *= 10)
        {
            startTime = DateTime.Now;
            CreatePdf("D:\\Pcm Test", i);
            elapsedTime = (DateTime.Now - startTime);

            Console.WriteLine($"{i:d04} pages: {elapsedTime.TotalSeconds}.{elapsedTime.Milliseconds}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + ": " + ex.StackTrace);
    }
    finally
    {
        Console.Read();
    }
}

public static void CreatePdf(String path, int numberOfPages)
{
    PdfFont fontBold = PdfFontFactory.CreateFont(@"C:\Users\Aydin\Desktop\arialbd.ttf", true);
    PdfFont fontComic = PdfFontFactory.CreateFont(@"C:\Users\Aydin\Desktop\calibri.ttf", true);
    // Set up the document.     

    using (var rgbCSProfile = new FileStream(@"C:\Users\Aydin\Downloads\sRGB_CS_profile.icm", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var pdfWriter = new PdfWriter($"{path}\\csharp_{numberOfPages}_pages.pdf"))
    {
        PdfADocument pdfDocument = new PdfADocument(pdfWriter, PdfAConformanceLevel.PDF_A_3B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", rgbCSProfile));
        pdfDocument.SetTagged();
        pdfDocument.GetDocumentInfo().SetTitle("Reference Document");
        pdfDocument.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
        pdfDocument.GetCatalog().SetLang(new PdfString("en-US"));

        Document document = new Document(pdfDocument);

        // Add a table to every page.
        for (int i = 0; i < numberOfPages; i++)
        {

            Table table = new Table(5, true);
            table.SetWidth(UnitValue.CreatePercentValue(100));

            document.Add(table);

            for (int j = 0; j < 5; j++)
            {
                Cell cell = new Cell(2, 1)
                        .Add(new Paragraph("Header " + j).SetMultipliedLeading(0.5f))
                        .SetFont(fontBold)
                        .SetFontSize(20)
                        .SetBackgroundColor(ColorConstants.CYAN);

                table.AddHeaderCell(cell);
            }

            for (int j = 0; j < 225; j++)
            {
                if (j % 15 == 0) table.Flush();

                Cell cell = new Cell().Add(new Paragraph("Test " + j)
                                      .SetMultipliedLeading(0.5f))
                                      .SetFont(fontComic)
                                      .SetPaddingTop(4.1f);

                table.AddCell(cell);
            }

            table.Complete();
            document.Flush();
            document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        }
        document.Close();
    }
}
// Define other methods and classes here
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建表格时如何提高 iText 性能 的相关文章

  • ASP .NET MVC,创建类似路由配置的永久链接

    我需要帮助在 MVC 网站中创建类似 URL 路由的永久链接 Slug 已设置为 www xyz com profile slug 代码为 routes MapRoute name Profile url profile slug defa
  • 红宝石接球和效率

    catch在 Ruby 中意味着跳出深度嵌套的代码 在 Java 中 例如用Java也可以达到同样的效果try catch用于处理异常 但它被认为是糟糕的解决方案 而且效率非常低 在 Ruby 中 我们有处理异常的方法begin raise
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 从 Orchard 内的主题渲染图像

    我刚刚选择 Orchard 来构建我的博客 作为创建这个新博客的努力的一部分 我正在创建一个自定义主题 这个自定义主题同时具有 CSS 和图像 我的问题 我的问题基本上可以归结为 如何渲染属于主题一部分的图像 到目前为止我已经尝试过的 我尝
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • string.Compare 行为

    怎么会这样呢 这是从VS2008中的立即窗口获取的 string Compare 1 string Compare 0 0 1 从言论来看字符串比较 http msdn microsoft com en us library 84787k2
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • 哪些属性有助于运行时 .Net 性能?

    我正在寻找可用于通过向加载器 JIT 编译器或 ngen 提供提示来确保 Net 应用程序获得最佳运行时性能的属性 例如我们有可调试属性 http msdn microsoft com en us library k2wxda47 aspx
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are
  • 文件修改时间检查的成本

    对于Linux下包含少量字节的文件 我只需要处理自上次处理以来发生更改的时间 我通过调用 PHP 检查文件是否被更改clearstatcache filemtime 定期 由于整个文件总是很小 因此删除对 filemtime 的调用并通过将

随机推荐