How to create a table using PDFsharp?
Asked Answered
H

4

13

Just started using PDFsharp and it works fine, but now I want to create tables in my PDF, but tried other sources and found nothing.

So far I know how to use graph.drawString().

Hoopes answered 30/10, 2017 at 9:13 Comment(0)
S
10

I could not find any clear and simple example of a basic table-template. pdfSharp is a very powerful but extremely low level library, so it's difficult to draw rectangles and text with fixed positions. Anyway, here is a little complete example that shows how to draw a table:

protected void ExportGraf_Click(object sender, EventArgs e)
{
    PdfDocument document = new PdfDocument();
    document.Info.Title = "Table Example";

    for (int p=0; p<1; p++) 
    { 
        // Page Options
        PdfPage pdfPage = document.AddPage();
        pdfPage.Height = 842;//842
        pdfPage.Width = 590;

        // Get an XGraphics object for drawing
        XGraphics graph = XGraphics.FromPdfPage(pdfPage);

        // Text format
        XStringFormat format = new XStringFormat();
        format.LineAlignment = XLineAlignment.Near;
        format.Alignment = XStringAlignment.Near;
        var tf = new XTextFormatter(graph);
           
        XFont fontParagraph = new XFont("Verdana", 8, XFontStyle.Regular);

        // Row elements
        int el1_width = 80;
        int el2_width = 380;

        // page structure options
        double lineHeight = 20;
        int marginLeft = 20;
        int marginTop = 20;
           
        int el_height = 30;
        int rect_height = 17;

        int interLine_X_1 = 2;
        int interLine_X_2 = 2 * interLine_X_1;

        int offSetX_1 = el1_width;
        int offSetX_2 = el1_width + el2_width;

        XSolidBrush rect_style1 = new XSolidBrush(XColors.LightGray);
        XSolidBrush rect_style2 = new XSolidBrush(XColors.DarkGreen);
        XSolidBrush rect_style3= new XSolidBrush(XColors.Red);

        for (int i = 0; i < 30; i++)
        {
            double dist_Y = lineHeight * (i + 1);
            double dist_Y2 = dist_Y - 2;

            // header della G
            if (i == 0)
            {
                graph.DrawRectangle(rect_style2, marginLeft, marginTop, pdfPage.Width-2* marginLeft, rect_height);

                tf.DrawString("column1", fontParagraph, XBrushes.White,
                              new XRect(marginLeft, marginTop, el1_width, el_height), format);

                tf.DrawString("column2", fontParagraph, XBrushes.White,
                              new XRect(marginLeft + offSetX_1 + interLine_X_1, marginTop , el2_width, el_height), format);

                tf.DrawString("column3", fontParagraph, XBrushes.White,
                              new XRect(marginLeft + offSetX_2 + 2 * interLine_X_2, marginTop, el1_width, el_height), format);

                // stampo il primo elemento insieme all'header
                graph.DrawRectangle(rect_style1, marginLeft, dist_Y2 + marginTop, el1_width, rect_height);
                tf.DrawString("text1", fontParagraph, XBrushes.Black,
                              new XRect(marginLeft, dist_Y + marginTop, el1_width, el_height), format);

                //ELEMENT 2 - BIG 380
                            graph.DrawRectangle(rect_style1, marginLeft + offSetX_1 + interLine_X_1, dist_Y2 + marginTop, el2_width, rect_height);
                            tf.DrawString(
                                "text2",
                                fontParagraph,
                                XBrushes.Black,
                                new XRect(marginLeft + offSetX_1 + interLine_X_1, dist_Y + marginTop, el2_width, el_height),
                                format);


                            //ELEMENT 3 - SMALL 80

                            graph.DrawRectangle(rect_style1, marginLeft + offSetX_2 + interLine_X_2, dist_Y2 + marginTop, el1_width, rect_height);
                            tf.DrawString(
                                "text3",
                                fontParagraph,
                                XBrushes.Black,
                                new XRect(marginLeft + offSetX_2 + 2 * interLine_X_2, dist_Y + marginTop, el1_width, el_height),
                                format);
              

                    }
                        else { 

                        //if (i % 2 == 1)
                        //{
                        //  graph.DrawRectangle(TextBackgroundBrush, marginLeft, lineY - 2 + marginTop, pdfPage.Width - marginLeft - marginRight, lineHeight - 2);
                        //}

                        //ELEMENT 1 - SMALL 80
                        graph.DrawRectangle(rect_style1,  marginLeft, marginTop + dist_Y2, el1_width, rect_height);
                        tf.DrawString(
                
                            "text1",
                            fontParagraph,
                            XBrushes.Black,
                            new XRect(marginLeft, marginTop + dist_Y, el1_width, el_height),            
                            format);

                        //ELEMENT 2 - BIG 380
                        graph.DrawRectangle(rect_style1, marginLeft + offSetX_1 + interLine_X_1 , dist_Y2 + marginTop, el2_width, rect_height);
                        tf.DrawString(
                            "text2",
                            fontParagraph,
                            XBrushes.Black,
                            new XRect(marginLeft + offSetX_1 + interLine_X_1, marginTop + dist_Y, el2_width, el_height),
                            format);


                        //ELEMENT 3 - SMALL 80
         
                        graph.DrawRectangle(rect_style1, marginLeft + offSetX_2 + interLine_X_2, dist_Y2 + marginTop, el1_width, rect_height);
                        tf.DrawString(
                            "text3",
                            fontParagraph,
                            XBrushes.Black,
                            new XRect(marginLeft + offSetX_2 + 2 *interLine_X_2, marginTop + dist_Y, el1_width, el_height),
                            format);

                        }

                    }


            }


            const string filename = "C:\\Users\\Desktop\\test\\HelloWorld.pdf";
            document.Save(filename);

            //byte[] bytes = null;
            //using (MemoryStream stream = new MemoryStream())
            //{
            //    document.Save(stream, true);
            //    bytes = stream.ToArray();
            //}

            //SendFileToResponse(bytes, "HelloWorld_test.pdf");

        }

Notice you can print more pages within the document; just change the first "for".

It should render like this: like this.

Sassoon answered 29/1, 2021 at 16:45 Comment(1)
How to apply text warp in second row, if column 1 text is more than the width of column without changing its widthHomothallic
C
7

With PDFsharp: draw text, draw lines around it.

With MigraDoc (you already added that tag): add a Table to your document and add the columns, rows, and borders you need.

The MigraDoc samples that come with MigraDoc are all C#, but a VB.NET sample can be found on the forum.

VB.NET sample on official PDFsharp/MigraDoc forum:
http://forum.pdfsharp.net/viewtopic.php?f=8&t=3207

C# sample on official site that shows usage of tables:
http://pdfsharp.net/wiki/Invoice-sample.ashx

Ctenidium answered 30/10, 2017 at 9:18 Comment(0)
E
0

This example creates a table, but also shows you how to insert text, draw lines, squares, and set up margins. Still a work in progress.

//PdfSharpUtilities.cs

//*******************************************************************/     

    /* Usage example
        
    private void buttonRunExample_Click(object sender, EventArgs e)
    {
        PdfSharpUtilities pdf = new PdfSharpUtilities("test.pdf", true);

        pdf.drawSquare(new DPoint(0, 0), 3, 2, XBrushes.Purple);

        pdf.addText("Username", new DPoint(0, 4.5), 16);

        pdf.addText("Invoice", new DPoint(12.15, 1.5), 14);

        pdf.addText("Account: 69696969", new DPoint(0, 6));

        pdf.addText("Period: 2022-11", new DPoint(0, 7));

        pdf.addText("E-mail: [email protected]", new DPoint(0, 8));

        pdf.addText("Inventory:", new DPoint(0, 10));

        //Example table: to fill with example data leave contents = null
        pdf.drawTable(0, 11, 15.7, 3, XBrushes.LightGray, null);

        pdf.saveAndShow();

    }*/    
    
    //******************************************************************/

    public class PdfSharpUtilities
    {
        private double topMargin = 0;
        private double leftMargin = 0;
        private double rightMargin = 0;
        private double bottomMargin = 0;
        private double cm;

        private PdfDocument document;
        private PdfPage page;
        private XGraphics gfx;
        private XFont font;
        private XPen pen;
        private String outputPath;

        public PdfSharpUtilities(String argOutputpath, Boolean argAddMarginGuides = false)
        {
            this.outputPath = argOutputpath;

            //You’ll need a PDF document:
            this.document = new PdfDocument();

            //And you need a page:
            this.page = document.AddPage();
            this.page.Size = PageSize.Letter;

            //Define how much a cm is in document's units
            this.cm = new Interpolation().linearInterpolation(0, 0, 27.9, page.Height, 1);
            Console.WriteLine("1 cm:" + cm);

            //Drawing is done with an XGraphics object:

            this.gfx = XGraphics.FromPdfPage(page);

            this.font = new XFont("Arial", 12, XFontStyle.Bold);
            this.pen = new XPen(XColors.Black, 0.5);

            //Sugested margins

            topMargin = 2.5 * cm;
            leftMargin = 3 * cm;
            rightMargin = page.Width - (3 * cm);
            bottomMargin = page.Height - (2.5 * cm);

            if (argAddMarginGuides)
            {
                gfx.DrawString("+", font, XBrushes.Black, rightMargin, topMargin);
                gfx.DrawString("+", font, XBrushes.Black, leftMargin, topMargin);
                gfx.DrawString("+", font, XBrushes.Black, rightMargin, bottomMargin);
                gfx.DrawString("+", font, XBrushes.Black, leftMargin, bottomMargin);
            }

            Console.WriteLine("Page Width in cm:" + page.Width * cm);
            Console.WriteLine("Page Height in cm:" + page.Height * cm);

            Console.WriteLine("Top Margin in cm:" + topMargin);
            Console.WriteLine("Left Margin in cm:" + leftMargin);
            Console.WriteLine("Right Margin in cm:" + rightMargin);
            Console.WriteLine("Bottom Margin in cm:" + bottomMargin);
        }

        public void drawTable(double initialPosX, double initialPosY, double width, double height, XBrush xbrush, List<String[]> contents = null)
        {
            drawSquare(new DPoint(initialPosX, initialPosY), width, height, xbrush);

            if (contents == null)
            {
                contents = new List<String[]>();

                contents.Add(new string[] { "Type", "Size", "Weight", "Stock", "Tax", "Price" });
                contents.Add(new string[] { "Obo", "1", "45", "56", "16.00", "6.50" });
                contents.Add(new string[] { "Crotolamo", "2", "72", "63", "16.00", "19.00" });
            }

            int columns = contents[0].Length;
            int rows = contents.Count;

            double distanceBetweenRows = height / rows;
            double distanceBetweenColumns = width / columns;

            /*******************************************************************/
            // Draw the row lines
            /*******************************************************************/

            DPoint pointA = new DPoint(initialPosX, initialPosY);
            DPoint pointB = new DPoint(initialPosX + width, initialPosY);

            for (int i = 0; i <= rows; i++)
            {
                drawLine(pointA, pointB);

                pointA.y = pointA.y + distanceBetweenRows;
                pointB.y = pointB.y + distanceBetweenRows;
            }

            /*******************************************************************/
            // Draw the column lines
            /*******************************************************************/

            pointA = new DPoint(initialPosX, initialPosY);
            pointB = new DPoint(initialPosX, initialPosY + height);

            for (int i = 0; i <= columns; i++)
            {
                drawLine(pointA, pointB);

                pointA.x = pointA.x + distanceBetweenColumns;
                pointB.x = pointB.x + distanceBetweenColumns;
            }

            /*******************************************************************/
            // Insert text corresponding to each cell
            /*******************************************************************/

            pointA = new DPoint(initialPosX, initialPosY);

            foreach (String[] rowDataArray in contents)
            {
                foreach (String cellText in rowDataArray)
                {                    

                    this.gfx.DrawString(cellText, this.font, XBrushes.Black, new XRect(leftMargin + (pointA.x * cm), topMargin + (pointA.y * cm), distanceBetweenColumns * cm, distanceBetweenRows * cm), XStringFormats.Center);

                    pointA.x = pointA.x + distanceBetweenColumns;
                }

                pointA.x = initialPosX;
                pointA.y = pointA.y + distanceBetweenRows;
            }
        }

        public void addText(String text, DPoint xyStartingPosition, int size = 12)
        {
            this.gfx.DrawString(text, this.font, XBrushes.Black, leftMargin + (xyStartingPosition.x * cm), topMargin + (xyStartingPosition.y * cm));
        }

        public void drawSquare(DPoint xyStartingPosition, double width, double height, XBrush xbrush)
        {
            Console.WriteLine("Drawing square starting at: " + xyStartingPosition.x + "," + xyStartingPosition.y + " width: " + width + " height: " + height);
            this.gfx.DrawRectangle(xbrush, new XRect(leftMargin + (xyStartingPosition.x * cm), topMargin + (xyStartingPosition.y * cm), (width * cm), (height * cm)));
        }

        public void drawLine(DPoint fromXyPosition, DPoint toXyPosition)
        {
            this.gfx.DrawLine(this.pen, leftMargin + (fromXyPosition.x * cm), topMargin + (fromXyPosition.y * cm), leftMargin + (toXyPosition.x * cm), topMargin + (toXyPosition.y * cm));
        }

        public void saveAndShow(Boolean argShowAfterSaving = true)
        {
            document.Save(this.outputPath);

            if (argShowAfterSaving)
            {
                Process.Start(this.outputPath);
            }
        }
    }

//DPoint.cs

public class DPoint
    {
        public double x { get; set; }
        public double y { get; set; }

        public DPoint(double x, double y)
        {
            this.x = x;
            this.y = y;
        }
    }

//Interpolation.cs

 public double linearInterpolation(double x0, double y0, double x1, double y1, double xd)
        {
            /*******************************************************************/                           
            //
            //  x0          ------->    y0
            //  given x     ------->    what is y?
            //  x1          ------->    y1
            /*******************************************************************/

            return (y0 + ((y1 - y0) * ((xd - x0) / (x1 - x0))));
        }

Code screenshot

Ekaterina answered 4/11, 2022 at 8:37 Comment(2)
Nice start, but does not handle page breaks. XUnit supports cm, mm, inch, point, ... - why use DPoint? One cm is XUnit.FromCentimeter(1). Where I live default page size is A4.Ctenidium
You are absolutely right, I got a severe case of tunnel vision here. Let me fix it and update the code accordingly.Ekaterina
J
-1

This work example, with MigroDoc. I changed a little from that example

    static Table table;
    static Document document;
    static TextFrame addressFrame;
   
    public static void Main()
    {
       
        const PdfFontEmbedding embedding = PdfFontEmbedding.Always;
        PdfDocumentRenderer render = new PdfDocumentRenderer(true, embedding);
        Document doc = CreateDocument();
        render.Document = doc;
        render.DocumentRenderer = render.DocumentRenderer;
        render.RenderDocument();
        render.PdfDocument.Save(@"D:\PDF1.pdf");
        Process.Start(@"D:\PDF1.pdf");
    }

    public static Document CreateDocument()
    {
        // Create a new MigraDoc document
        document = new Document();
        document.Info.Title = "A sample invoice";
        document.Info.Subject = "Demonstrates how to create an invoice.";
        document.Info.Author = "Stefan Lange";

        DefineStyles();

        CreatePage();

        FillContent();

        return document;
    }

    static void DefineStyles()
    {
        // Get the predefined style Normal.
        Style style = document.Styles["Normal"];
        // Because all styles are derived from Normal, the next line changes the 
        // font of the whole document. Or, more exactly, it changes the font of
        // all styles and paragraphs that do not redefine the font.
        style.Font.Name = "Arial";

        style = document.Styles[StyleNames.Header];
        style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);

        style = document.Styles[StyleNames.Footer];
        style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);

        // Create a new style called Table based on style Normal
        style = document.Styles.AddStyle("Table", "Normal");
        style.Font.Name = "Arial";
        style.Font.Size = 9;

        // Create a new style called Reference based on style Normal
        style = document.Styles.AddStyle("Reference", "Normal");
        style.ParagraphFormat.SpaceBefore = "5mm";
        style.ParagraphFormat.SpaceAfter = "5mm";
        style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right);
    }

    static void CreatePage()
    {
        Section section = document.AddSection();
        
        
        // Create footer
        Paragraph paragraph = section.Footers.Primary.AddParagraph();
        paragraph.AddText("PowerBooks Inc · Sample Street 42 · 56789 Cologne · Germany");
        paragraph.Format.Font.Size = 9;
        paragraph.Format.Alignment = ParagraphAlignment.Center;

        // Create the text frame for the address
        addressFrame = section.AddTextFrame();
        addressFrame.Height = "3.0cm";
        addressFrame.Width = "7.0cm";
        addressFrame.Left = ShapePosition.Left;
        addressFrame.RelativeHorizontal = RelativeHorizontal.Margin;
        addressFrame.Top = "5.0cm";
        addressFrame.RelativeVertical = RelativeVertical.Page;

        // Put sender in address frame
        paragraph = addressFrame.AddParagraph("PowerBooks Inc · Sample Street 42 · 56789 Cologne");
        paragraph.Format.Font.Name = "Arial";
        paragraph.Format.Font.Size = 7;
        paragraph.Format.SpaceAfter = 3;
        
        
        
        // Add the print date field
        paragraph = section.AddParagraph();
        paragraph.Format.SpaceBefore = "8cm";
        paragraph.Style = "Reference";
        paragraph.AddFormattedText("INVOICE");
        paragraph.AddTab();
        paragraph.AddText("Hello World");
        paragraph.AddDateField("dd.MM.yyyy");

        // Create the item table
        table = section.AddTable();
        table.Style = "Table";
        table.Borders.Color = Colors.Black;
        table.Borders.Width = 0.25;
        table.Borders.Left.Width = 0.5;
        table.Borders.Right.Width = 0.5;
        table.Rows.LeftIndent = 0;

        // Before you can add a row, you must define the columns
        Column column = table.AddColumn("1cm");
        column.Format.Alignment = ParagraphAlignment.Center;

        column = table.AddColumn("2.5cm");
        column.Format.Alignment = ParagraphAlignment.Right;

        column = table.AddColumn("3cm");
        column.Format.Alignment = ParagraphAlignment.Right;

        column = table.AddColumn("3.5cm");
        column.Format.Alignment = ParagraphAlignment.Right;

        column = table.AddColumn("2cm");
        column.Format.Alignment = ParagraphAlignment.Center;

        column = table.AddColumn("4cm");
        column.Format.Alignment = ParagraphAlignment.Right;

        // Create the header of the table
        Row row = table.AddRow();
        row.HeadingFormat = true;
        row.Format.Alignment = ParagraphAlignment.Center;
        row.Format.Font.Bold = true;
        row.Shading.Color = Colors.Red;
        row.Cells[0].AddParagraph("Item");
        row.Cells[0].Format.Font.Bold = false;
        row.Cells[0].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[0].VerticalAlignment = VerticalAlignment.Bottom;
        row.Cells[0].MergeDown = 1;
        row.Cells[1].AddParagraph("Title and Author");
        row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[1].MergeRight = 3;
        row.Cells[5].AddParagraph("Extended Price");
        row.Cells[5].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
        row.Cells[5].MergeDown = 0;

        row = table.AddRow();
        row.HeadingFormat = true;
        row.Format.Alignment = ParagraphAlignment.Center;
        row.Format.Font.Bold = true;
        row.Shading.Color = Colors.Blue;
        row.Cells[1].AddParagraph("Quantity");
        row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[2].AddParagraph("Unit Price");
        row.Cells[2].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[3].AddParagraph("Discount (%)");
        row.Cells[3].Format.Alignment = ParagraphAlignment.Left;
        row.Cells[4].AddParagraph("Taxable");
        row.Cells[4].Format.Alignment = ParagraphAlignment.Left;

        table.SetEdge(0, 0, 6, 2, Edge.Box, BorderStyle.Single, 0.75, Color.Empty);
    }

    static void FillContent()
    {
        

        Paragraph paragraph = addressFrame.AddParagraph();


        // Iterate the invoice items
        double totalExtendedPrice = 0;
       
            double quantity = 200;
            double price = 40;
            double discount = 5;
        for (int i = 0; i < 10; i++)
        {


            // Each item fills two rows
            Row row1 = table.AddRow();
            Row row2 = table.AddRow();
            row1.TopPadding = 1.5;
            row1.Cells[0].Shading.Color = Colors.Gray;
            row1.Cells[0].VerticalAlignment = VerticalAlignment.Center;
            row1.Cells[0].MergeDown = 1;
            row1.Cells[1].Format.Alignment = ParagraphAlignment.Left;
            row1.Cells[1].MergeRight = 3;
            row1.Cells[5].Shading.Color = Colors.Gray;
            row1.Cells[5].MergeDown = 1;

            row1.Cells[0].AddParagraph("Hello World 300");
            paragraph = row1.Cells[1].AddParagraph();
            paragraph.AddFormattedText("Hello World 234", TextFormat.Bold);
            paragraph.AddFormattedText(" by ", TextFormat.Italic);
            paragraph.AddText("Hello World 200");
            row2.Cells[1].AddParagraph("Hello World 125");
            row2.Cells[2].AddParagraph(price.ToString("0.00") + " €");
            row2.Cells[3].AddParagraph(discount.ToString("0.0"));
            row2.Cells[4].AddParagraph();
            row2.Cells[5].AddParagraph(price.ToString("0.00"));
            double extendedPrice = quantity * price;
            extendedPrice = extendedPrice * (100 - discount) / 100;
            row1.Cells[5].AddParagraph(extendedPrice.ToString("0.00") + " €");
            row1.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
            totalExtendedPrice += extendedPrice;

            table.SetEdge(0, table.Rows.Count - 2, 6, 2, Edge.Box, BorderStyle.Single, 0.75);

        }

    }
Judie answered 21/2, 2021 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.