zoukankan      html  css  js  c++  java
  • [转]Create/Read Advance PDF Report using iTextSharp in C# .NET: Part I

    本文转自:https://www.codeproject.com/Articles/686994/Create-Read-Advance-PDF-Report-using-iTextSharp-in

    Create/Read/Write Advance PDF Report using iTextSharp.DLL in Desktop, Mobile, Web Application

    Contents


    The following two contents are added in this updated version:

    Introduction

    Recently I was looking for an Advance Tool to create complex PDF Report in C#.Net and I found iTextSharp. The main problem is that lacks of Documentation. Yes, there are a few examples in C#, but that is not sufficient to the Beginners and the examples are in older version of iTextSharp, there are lots of change in the latest version. So, it will be difficult for beginners to convert older version to latest version. Besides, I think that if I write an Article on this, then it will help me also as a future reference as I'll describe each functionality of this library with example. Frankly speaking, in this Article, you find all the examples from Chapter 1 of the book iText in Action, Second Edition which is written for Java Developers. I'll explain all the examples of the rest Chapters in my next release of this Article. So if any one is interested in using this library, he/she will get a good kick start.

    To know the history or any other details of iTextSharp, please go through the Official Website

    Requirements

    • To compile this library, you need a C# 2008 compiler or better, Visual Studio 2008 or Visual C# 2008 Express Edition
    • This library code will run in:
      • .NET 2.0
      • .NET 3.0
      • .NET 3.5
      • .NET 4.0
      • .NET 4.0 Client Profile
      • .NET 4.5
      • .NET 4.5 Client Profile

    Installation

    Or you can download the library DLL from the above link or from the SourceForge. Then do the following:

    • Add the following library into your project by adding reference to that library DLL. Just see the image below:

      Adding iTextSharp 5.4.4 DLL
    • The necessary namespace that you have to add into your C# file to do what are in this Article are::
      • iTextSharp.text
      • iTextSharp.text.pdf

    Quick Start

    Creating PDF Document in 6 Steps:

    • Step 1: Create a System.IO.FileStream object:
      FileStream fs = new FileStream("Chapter1_Example1.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
    • Step 2: Create a iTextSharp.text.Document object:
      Document doc = new Document();
    • Step 3: Create a iTextSharp.text.pdf.PdfWriter object. It helps to write the Document to the Specified FileStream:
      PdfWriter writer = PdfWriter.GetInstance(doc, fs);
    • Step 4: Openning the Document:
      doc.Open();
    • Step 5: Adding a Paragraph by creating a iTextSharp.text.Paragraph object:
      doc.Add(new Paragraph("Hello World"));
    • Step 6: Closing the Document:
      doc.Close();

    Working with Page Size of PDF Document:

    Creating a Page of specified size, we must have to create a iTextSharp.text.Rectangle object and Passing the size as argument to its constructor. There are a few way to define Page Size:

    • First Way to define Page Size: 
      Creating Page Size by Pixels or Inch. NOTE: In iTextSharp library, unit is 'point'. 72 points = 1 inch. Suppose we want to create a PDF File of width = 2 inch & height = 10 inch, then we need 144pt for 2 inch & 72pt for 10 inch. Lets see, how to do this:
      Rectangle rec = new Rectangle(144, 720);
    • Second Way to define Page Size:
      Taking Page Size from in-built iTextSharp.text.PageSize class:
      Rectangle rec2 = new Rectangle(PageSize.A4);
      The following are the Supported in-built Page Size. Read the full Documentation of Page Size:
      • _11X17
      • A0
      • A1
      • A10
      • A2
      • A3
      • A4
      • A4_LANDSCAPE
      • A5
      • A6
      • A7
      • A8
      • A9
      • ARCH_A
      • ARCH_B
      • ARCH_C
      • ARCH_D
      • ARCH_E
      • B0
      • B1
      • B10
      • B2
      • B3
      • B4
      • B5
      • B6
      • B7
      • B8
      • B9
      • CROWN_OCTAVO
      • CROWN_QUARTO
      • DEMY_OCTAVO
      • DEMY_QUARTO
      • EXECUTIVE
      • FLSA
      • FLSE
      • HALFLETTER
      • ID_1
      • ID_2
      • ID_3
      • LARGE_CROWN_OCTAVO
      • LARGE_CROWN_QUARTO
      • LEDGER
      • LEGAL
      • LEGAL_LANDSCAPE
      • LETTER
      • LETTER_LANDSCAPE
      • NOTE
      • PENGUIN_LARGE_PAPERBACK
      • PENGUIN_SMALL_PAPERBACK
      • POSTCARD
      • ROYAL_OCTAVO
      • ROYAL_QUARTO
      • SMALL_PAPERBACK
      • TABLOID
    • Third Way to define Page Size:
      Rotating Document i.e. height becomes width & vice-versa:
      Rectangle rec3 = new Rectangle(PageSize.A4.Rotate());

    Now, just pass this iTextSharp.text.Rectangle object (any one) i.e. either 'rec', or 'rec2' or 'rec3' to the iTextSharp.text.Document's constructor during object creation like below:

    Document doc = new Document(rec);

    Setting Background Color of PDF Document:

    There are a few ways to set background color:

    • First Way to Set Background Color:
      It takes the object of iTextSharp.text.BaseColor. BaseColor constructor takes in-built System.Drawing.Color object Or you can pass RGB values to the constructor in different forms:
      rec.BackgroundColor = new BaseColor(System.Drawing.Color.WhiteSmoke);
    • Second Way to Set Background Color:
      It takes the object of iTextSharp.text.pdf.CMYKColor. CMYKColor constructor takes only CMYK values in different forms:
      rec2.BackgroundColor = new CMYKColor(25, 90, 25, 0);

    Setting Page Margins of PDF Document:

    Margins can be set during Document object creation like Page Size
    Suppose we set the margins as below:

    • Left Margin: 0.5 inch
    • Right Margin: 1 inch
    • Top Margin: 1.5 inch
    • Bottom Margin: 2.5 inch

    So, we need to do set the following points for the Left, Right, Top, Bottom Margins respectively as we already know that iTextSharp library only understand points where 72 points = 1 inch.

    • Left Margin: 36pt => 0.5 inch
    • Right Margin: 72pt => 1 inch
    • Top Margin: 108pt => 1.5 inch
    • Bottom Margini: 180pt => 2.5 inch

    Lets implement:

    Document doc = new Document(PageSize.A4, 36, 72, 108, 180);

    Setting Text Alignment in PDF Document:

    Alignment is one of the property of iTextSharp.text.Paragraph's object. iTextSharp Library provides various types of Alignments. These Alignments can be access through iTextSharp.text.Element class. The following are Alignment types provides iTextSharp:

    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_BASELINE">
      			ALIGN_BASELINE</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_BOTTOM">
      			ALIGN_BOTTOM</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_CENTER">
      			ALIGN_CENTER</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_JUSTIFIED">
      			ALIGN_JUSTIFIED</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_JUSTIFIED_ALL">
      			ALIGN_JUSTIFIED_ALL</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_LEFT">
      			ALIGN_LEFT</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_MIDDLE">
      			ALIGN_MIDDLE</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_RIGHT">
      			ALIGN_RIGHT</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_TOP">
      			ALIGN_TOP</a>
      [^]
    • <a href="http://api.itextpdf.com/itext/com/itextpdf/text/Element.html#ALIGN_UNDEFINED">
      			ALIGN_UNDEFINED</a>
      [^]

    As we already see the iTextSharp.text.Document's constructor takes iTextSharp.text.Paragraph's object during Document creation. So, after creating the Paragraph object and setting Alignment property, we can pass this object to iTextSharp.text.Document's constructor during Document ceration. Lets implement:

    Paragraph para = new Paragraph("Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World");
    // Setting paragraph's text alignment using iTextSharp.text.Element class
    para.Alignment = Element.ALIGN_JUSTIFIED;
    // Adding this 'para' to the Document object
    doc.Add(para);

    Setting Meta Information or Properties of a PDF Document:

    The following Meta information of PDF Document, you can set through iTextSharp.text.Document's methods by creating its object i.e. doc here:

    • Author Name[^]
    • Creation Date[^]
    • Creator Name[^]
    • Header Name & Content[^]
    • Keywords[^]
    • Langugae[^]
    • Producer[^]
    • Subject[^]
    • Title[^]

    Lets implement a few of them:

    // Setting Document properties e.g.
    // 1. Title
    // 2. Subject
    // 3. Keywords
    // 4. Creator
    // 5. Author
    // 6. Header
    doc.AddTitle("Hello World example");
    doc.AddSubject("This is an Example 4 of Chapter 1 of Book 'iText in Action'");
    doc.AddKeywords("Metadata, iTextSharp 5.4.4, Chapter 1, Tutorial");
    doc.AddCreator("iTextSharp 5.4.4");
    doc.AddAuthor("Debopam Pal");
    doc.AddHeader("Nothing", "No Header");

    Now after openning this PDF file, right click over it and click Properties, then you'll see the following:

    PDF Document Properties

    Creating a Multipage Document:

    We can create a new page through iTextSharp.text.Document's NewPage() method by creating its object. Lets add five pages in PDF Document:

    for (int i = 1; i <= 5; i++)
    {
        doc.NewPage();
        doc.Add(new Paragraph(string.Format("This is a page {0}", i)));
    }

    Creating a New PDF Document from an existing PDF Document:

    We can read from a PDF Document using iTextSharp.text.pdf.PdfReader's object and write it to another PDF Document using iTextSharp.text.pdf.PdfStamper's object. Lets implement:

    string originalFile = "Original.pdf";
    string copyOfOriginal = "Copy.pdf";
    using (FileStream fs = new FileStream(originalFile, FileMode.Create, FileAccess.Write, FileShare.None))
    using (Document doc = new Document(PageSize.LETTER))
    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
    {
        doc.Open();
        doc.Add(new Paragraph("Hi! I'm Original"));
        doc.Close();
    }
    PdfReader reader = new PdfReader(originalFile);
    using (FileStream fs = new FileStream(copyOfOriginal, FileMode.Create, FileAccess.Write, FileShare.None))
    // Creating iTextSharp.text.pdf.PdfStamper object to write
    // Data from iTextSharp.text.pdf.PdfReader object to FileStream object
    using (PdfStamper stamper = new PdfStamper(reader, fs)) { }

    Adding Watermark to PDF Document using Layer:

    Watermark can be add after creating the PDF Dodument in iTextSharp Library. Here I'll add Watermark to existing PDF Document i.e. Original.pdf, through creating a iTextSharp.text.pdf.PdfLayer object. Lets implement:

    string watermarkedFile = "Watermarked.pdf";
    // Creating watermark on a separate layer
    // Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
    PdfReader reader1 = new PdfReader(originalFile);
    using (FileStream fs = new FileStream(watermarkedFile, FileMode.Create, FileAccess.Write, FileShare.None))
    // Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object
    using (PdfStamper stamper = new PdfStamper(reader1, fs))
    {
        // Getting total number of pages of the Existing Document
        int pageCount = reader1.NumberOfPages;
    
        // Create New Layer for Watermark
        PdfLayer layer = new PdfLayer("WatermarkLayer", stamper.Writer);
        // Loop through each Page
        for (int i = 1; i <= pageCount; i++)
        {
            // Getting the Page Size
            Rectangle rect = reader1.GetPageSize(i);
    
            // Get the ContentByte object
            PdfContentByte cb = stamper.GetUnderContent(i);
    
            // Tell the cb that the next commands should be "bound" to this new layer
            cb.BeginLayer(layer);
            cb.SetFontAndSize(BaseFont.CreateFont(
              BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 50);
    
            PdfGState gState = new PdfGState();
            gState.FillOpacity = 0.25f;
            cb.SetGState(gState);
    
            cb.SetColorFill(BaseColor.BLACK);
            cb.BeginText();
            cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, rect.Width / 2, rect.Height / 2, 45f);
            cb.EndText();
    
            // Close the layer
            cb.EndLayer();
        }
    }

    The created PDF Document is below:

    Watermarked.pdf

    Removing Watermark from the just created Watermarked Document by Removing Layer:

    Whenever we add Layer in PDF Document, then the content of the Layer resides under OCG Group. So if I remove this Layer we can remove the content of the Layer also e.g. here it is Watermark Text. To remove all the Layers from PDF Document, you have to remove OCG Group completely from the Document using reader.Catalog.Remove(PdfName.OCPROPERTIES). Now follow the Steps below to remove the Watermark Text from Layer:

    • Read the existing watermarked document using iTextSharp.text.pdf.PdfReader's object
    • Taking each Page in the iTextSharp.text.pdf.PdfDictionary's object using GetPageN(int pageNumber) method of iTextSharp.text.pdf.PdfReader's object.
    • Taking the Content of the Page in the iTextSharp.text.pdf.PdfArray's object using GetAsArray(PdfName.CONTENTS) method of iTextSharp.text.pdf.PdfDictionary's object
    • Loop through this array and Get each element as iTextSharp.text.pdf.PRStream's object using GetAsStream(int arrayIndex) method of iTextSharp.text.pdf.PdfArray's object
    • Convert each stream into Bytes using Static method
      GetStreamBytes(PRStream
      			stream)
      of iTextSharp.text.pdf.PdfReader class
    • Convert these Bytes into String using
      System.Text.Encoding.ASCII.GetString(byte[]
      			bytes)
      method
    • Search for the String "/OC" and also the Watermarked Text. If found then remove it by giving it zero length and zero data using two methods: Put() & SetData() of iTextSharp.text.pdf.PRStream class
    • Write this modified document exists in the reader to a new document using iTextSharp.text.pdf.PdfStamper's object

    Lets Implement it:

    // Removing the layer created above
    // 1. First we bind a reader to the watermarked file
    // 2. Then strip out a branch of things
    // 3. Finally use a simple stamper to write out the edited reader
    PdfReader reader2 = new PdfReader(watermarkedFile);
    
    // NOTE: This will destroy all layers in the Document, only use if you don't have any addtional layers
    // Remove the OCG group completely from the Document: reader2.Catalog.Remove(PdfName.OCPROPERTIES);
    
    // Clean up the reader, optional
    reader2.RemoveUnusedObjects();
    
    // Placeholder variables
    PRStream stream;
    string content;
    PdfDictionary page;
    PdfArray contentArray;
    
    // Get the number of pages
    int pageCount2 = reader2.NumberOfPages;
    
    // Loop through each page
    for (int i = 1; i <= pageCount2; i++)
    {
        // Get the page
        page = reader2.GetPageN(i);
    
        // Get the raw content
        contentArray = page.GetAsArray(PdfName.CONTENTS);
    
        if (contentArray != null)
        {
            // Loop through content
            for (int j = 0; j < contentArray.Size; j++)
            {
                stream = (PRStream)contentArray.GetAsStream(j);
    
                // Convert to a String, NOTE: you might need a different encoding here
                content = System.Text.Encoding.ASCII.GetString(PdfReader.GetStreamBytes(stream));
    
                //Look for the OCG token in the stream as well as our watermarked text
                if (content.IndexOf("/OC") >= 0 && content.IndexOf(watermarkText) >= 0)
                {
                    //Remove it by giving it zero length and zero data
                    stream.Put(PdfName.LENGTH, new PdfNumber(0));
                    stream.SetData(new byte[0]);
                }
            }
        }
    }
    
    // Write the content out
    using (FileStream fs = new FileStream(unwatermarkedFile, 
              FileMode.Create, FileAccess.Write, FileShare.None))
    using (PdfStamper stamper = new PdfStamper(reader2, fs)) { }

    Adding Watermark to each Page during Creation:

    Now, we already know that, watermark cannot be add during Page creation, it have to add after document creation. So, I've created a class PDFWriterEvents which implements the interface iTextSharp.text.pdf.IPdfPageEvent and modify the event OnStartPage. This interface contains a set of events from the Openning & to Closing the PDF Document. The events are following:

    • public void OnOpenDocument(PdfWriter writer, Document document)
    • public void OnCloseDocument(PdfWriter writer, Document document)
    • public void OnStartPage(PdfWriter writer, Document document)
    • public void OnEndPage(PdfWriter writer, Document document)
    • public void OnParagraph(PdfWriter writer, Document document, float paragraphPosition)
    • public void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition)
    • public void OnChapter(PdfWriter writer, Document document, float paragraphPosition,
      			Paragraph title)
    • public void OnChapterEnd(PdfWriter writer, Document document, float paragraphPosition)
    • public void OnSection(PdfWriter writer, Document document, float paragraphPosition,
      			int depth, Paragraph title)
    • public void OnSectionEnd(PdfWriter writer, Document document, float paragraphPosition)
    • public void OnGenericTag(PdfWriter writer, Document document, Rectangle rect,
      			String text)

    You may modify other events accroding to your needs which occured against a particular action. Let see the which I've created:

    // Creating Watermark inside OnStartPage Event by implementing IPdfPageEvent interface
    // So that, dusring Page Creation, Watermark will be create
    class PDFWriterEvents : IPdfPageEvent
    {
        string watermarkText;
        float fontSize = 80f;
        float xPosition = 300f;
        float yPosition = 800f;
        float angle = 45f;
    
        public PDFWriterEvents(string watermarkText, float fontSize = 80f, 
           float xPosition = 300f, float yPosition = 400f, float angle = 45f)
        {
            this.watermarkText = watermarkText;
            this.xPosition = xPosition;
            this.yPosition = yPosition;
            this.angle = angle;
        }
    
        public void OnOpenDocument(PdfWriter writer, Document document) { }
        public void OnCloseDocument(PdfWriter writer, Document document) { }
        public void OnStartPage(PdfWriter writer, Document document)
        {
            try
            {
                PdfContentByte cb = writer.DirectContentUnder;
                BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
                cb.BeginText();
                cb.SetColorFill(BaseColor.LIGHT_GRAY);
                cb.SetFontAndSize(baseFont, fontSize);
                cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, xPosition, yPosition, angle);
                cb.EndText();
            }
            catch (DocumentException docEx)
            {
                throw docEx;
            }
        }
        public void OnEndPage(PdfWriter writer, Document document) { }
        public void OnParagraph(PdfWriter writer, Document document, float paragraphPosition) { }
        public void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) { }
        public void OnChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { }
        public void OnChapterEnd(PdfWriter writer, Document document, float paragraphPosition) { }
        public void OnSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) { }
        public void OnSectionEnd(PdfWriter writer, Document document, float paragraphPosition) { }
        public void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { }
    }

    Lets see how & when you use the object of this class:

    using (FileStream fs = new FileStream(
          "Watermark_During_Page_Creation.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
    using (Document doc = new Document(PageSize.LETTER))
    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
    {
        writer.PageEvent = new PDFWriterEvents("This is a Test");
        doc.Open();
        doc.Add(new Paragraph("This is a page 1"));
        doc.Close();
    }

    See, OnStartPage event called during adding a new paragraph. So I don't need to add watermark later:)

    Export/Print/Output the PDF File directly to the Client without saving it to the Disk:

    We can create PDF File in memory by creatig System.IO.MemorySystem's object. Lets see:

    using (MemoryStream ms = new MemoryStream())
    using(Document document = new Document(PageSize.A4, 25, 25, 30, 30))
    using(PdfWriter writer = PdfWriter.GetInstance(document, ms))
    {
        document.Open();
        document.Add(new Paragraph("Hello World"));
        document.Close();
        writer.Close();
        ms.Close();
        Response.ContentType = "pdf/application";
        Response.AddHeader("content-disposition", "attachment;filename=First_PDF_document.pdf");
        Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
    }

    Setting Viewer Preferences of a PDF Document:

    The values of the different ViewerPreferences were originally stored in iTextSharp.text.pdf.PdfWriter class as an integer constant. You can set the ViewerPreferences by following two ways:

    • By setting property ViewerPreferences of iTextSharp.text.pdf.PdfWriter class. To know all the ViewerPreferences and its purpose, please read this first. E.g.-
      writer.ViewerPreferences = PdfWriter.HideMenubar;
    • By calling method AddViewerPreference(PdfName key, PdfObject value) of iTextSharp.text.pdf.PdfWriter's object. To know which value is appropiate for which key, read this first. E.g.-
      writer.AddViewerPreference(PdfName.HIDEMENUBAR, new PdfBoolean(true));

    Encrypting a PDF Document:

    By SetEncryption() method of iTextSharp.text.pdf.PdfWriter's object, we can encrypt a PDF document. Read full documentation of this method here. To know all the encryption types, click here. E.g.-

    writer.SetEncryption(PdfWriter.STRENGTH40BITS, null, null, PdfWriter.ALLOW_COPY);

    Declaration

    Please download the source code for detail. I hope you'll understand as the source
    			code is documented. If any doubt, just post your comment below. Thank you.

    References

    History

    25th Nov, 2013: PART-I Release. PART-II will release soon :)
  • 相关阅读:
    2021.07.14牛客学习
    2021.07.13学习总结
    new和malloc区别(自己口头描述)以及delete用法
    排序整理(c++实现),搭配图解
    如何将bilibili上缓存的文件转成MP4
    第07组 团队Git现场编程实战
    第二次结队编程作业
    团队项目-需求分析报告
    团队项目-选题报告
    第一次结对编程作业
  • 原文地址:https://www.cnblogs.com/freeliver54/p/12124488.html
Copyright © 2011-2022 走看看