创建表时如何提高iText性能 [英] How to improve iText performance when creating tables

查看:183
本文介绍了创建表时如何提高iText性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,Stackoverflow真棒

Hey awesome Stackoverflow people

我目前正在评估是否应该将iText 7.1.9用于Java或C#. 为此,我创建了一个测试用例,其中我编写了一个包含一堆页面的PDF,每个页面包含一个大表(下面的代码).

I am currently evaluating if we should use iText 7.1.9 for Java or C#. To do this, I created a test case where I write a single PDF with a bunch of pages, each containing a big table (code below).

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

In Java, creating a PDF with x pages yields the following results:

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

这是合理的表现.但是,当我将完全相同的代码移植到C#.Net时,我感到非常震惊:

This is reasonably performant. However, when I ported the exact same code to C# .Net, I got quite the shock:

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

使用Java创建的PDF的大小与C#的大小相同,并且文件看起来完全相同. 但是,C#似乎呈线性扩展,而Java设法以某种方式设法优化了较大的PDF.

The PDFs created with Java have the same size as the C# ones and the files look exactly the same. C# however seems to scale linearly while Java somehow manages to optimize bigger PDFs.

由于我们宁愿使用C#,因此问题如下:

Since we'd rather use C# the questions are:

  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版本的性能...

It's not your code, it's the library, I setup a test project and best I could do was shave off around 20%, but that doesn't come close to the performance of the java version...

  • 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

这篇关于创建表时如何提高iText性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆