FlexGrid for WinForms | ComponentOne
Save, Load and Print / Save / Export to PDF
In This Topic
    Export to PDF
    In This Topic

    The easiest way of saving FlexGrid as a PDF is to use the System.PrintDocument class. You can set its PrinterName property to "Microsoft Print to PDF" and invoke Print method of the class.

    var printDocument = _flexGrid.PrintParameters.PrintDocument;
    printDocument.DocumentName = "Export to PDF";
    printDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF";
    // Print document into Microsoft PDF printer
     printDocument.Print();       
    
    Dim printDocument = _flexGrid.PrintParameters.PrintDocument
    printDocument.DocumentName = "Export to PDF"
    printDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF"
    ' Print document into Microsoft PDF printer
    printDocument.Print()             
    

    However, this approach has some limitations and it does not let you set advanced options such as setting borders, printing by specific page or column breaks etc. To implement these kind of advanced export options, you can use the C1PrintDocument class of the C1PrintDocument library shipped with ComponentOne WinForms Edition as shown in the section below.

    Advanced Export to PDF

    To export a grid to PDF with advanced options, you need to create images of grid by defining the rows and columns per page and hence, finding the row and column range to be drawn on each page. Then, add these images to generate a PDF using the C1PrintDocument class. Below are the detailed steps and sample code to implement the advanced export to PDF.

    Step 1: Create Ranges

    First, you need to set the UserData property according to the defined rows per page and columns per page. This helps in finding out the row and column range to be drawn on each page of the PDF document. So, this step acts as a ground to create images of the grid in the step below.

    // get rows/cols per page
    int rpp = 10;
    int cpp = 3;
    try
    {
        rpp = int.Parse(_rpp.Text);
        cpp = int.Parse(_cpp.Text);
    }
    catch { }
    
    // mark grid with row/column breaks
    for (int r = _flex.Rows.Fixed; r < _flex.Rows.Count; r++)
    {
        _flex.Rows[r].UserData = (r % rpp == 0)
            ? "*"
            : null;
    }
    for (int c = _flex.Cols.Fixed; c < _flex.Cols.Count; c++)
    {
        _flex.Cols[c].UserData = (c % cpp == 0)
            ? "*"
            : null;
    }
    
    Dim rpp As Integer = 10
    Dim cpp As Integer = 3
    Try
        rpp = Integer.Parse(_rpp.Text)
        cpp = Integer.Parse(_cpp.Text)
    Catch ex As Exception
    End Try
    For r As Integer = _flex.Rows.Fixed To _flex.Rows.Count - 1
        _flex.Rows(r).UserData = If((r Mod rpp = 0), "*", Nothing)
    Next
    
    For c As Integer = _flex.Cols.Fixed To _flex.Cols.Count - 1
        _flex.Cols(c).UserData = If((c Mod cpp = 0), "*", Nothing)
    Next
    

    Step 2: Create Grid Images

    Now, create a custom class (in this case, FlexPDFCreator) to create images of the grid using CreateImage method of the C1FlexGrid class. The images are created based on the UserData property set in the step above.

    public class FlexPdfCreator
    {
        // ** fields
        private ArrayList _images;
        private ArrayList _rowOnPage;
        private ArrayList _colOnPage;
        private int _rpp, _cpp;
        // ** ctor
        public FlexPdfCreator(C1FlexGrid flex, int _rpp, int _cpp)
        {
            // create page images
            _images = new ArrayList();
            _colOnPage = new ArrayList();
            _rowOnPage = new ArrayList();
            this._rpp = _rpp;
            this._cpp = _cpp;
    
            // initialize
            int r1, c1, r2, c2;
    
            // loop through columns looking for breaks
            c1 = c2 = flex.Cols.Fixed;
            for (int c = flex.Cols.Fixed; c < flex.Cols.Count; c++)
            {
                // check if this is a column break
                if (c == flex.Cols.Count - 1 ||
                    (flex.Cols[c].UserData != null && flex.Cols[c].UserData.ToString() == "*"))
                {
                    // found break, column range is c1-c
                    c2 = c;
    
                    // loop through rows looking for breaks
                    r1 = r2 = flex.Rows.Fixed;
                    for (int r = flex.Rows.Fixed; r < flex.Rows.Count; r++)
                    {
                        // look for next row break
                        if (r == flex.Rows.Count - 1 ||
                            (flex.Rows[r].UserData != null && flex.Rows[r].UserData.ToString() == "*"))
                        {
                            // found break, row range is r1-r
                            r2 = r;
    
                            // create image
                            _images.Add(flex.CreateImage(r1, c1, r2, c2));
                            _rowOnPage.Add(r2 - r1);
                            _colOnPage.Add(c2 - c1);
    
                            // update row range
                            r1 = r + 1;
                        }
                    }
    
                    // update column range
                    c1 = c + 1;
                }
            }
        }
    
    Public Class FlexPdfCreator
        Private _images As ArrayList
        Private _rowOnPage As ArrayList
        Private _colOnPage As ArrayList
        Private _rpp, _cpp As Integer
        Public Sub New(ByVal flex As C1FlexGrid, ByVal _rpp As Integer, ByVal _cpp As Integer)
            _images = New ArrayList()
            _colOnPage = New ArrayList()
            _rowOnPage = New ArrayList()
            Me._rpp = _rpp
            Me._cpp = _cpp
            Dim r1, c1, r2, c2 As Integer
            c1 = flex.Cols.Fixed
            c2 = flex.Cols.Fixed
            For c As Integer = flex.Cols.Fixed To flex.Cols.Count - 1
                If c = flex.Cols.Count - 1 OrElse (flex.Cols(c).UserData IsNot Nothing AndAlso flex.Cols(c).UserData.ToString() = "*") Then
                    c2 = c
                    r1 = flex.Rows.Fixed
                    r2 = flex.Rows.Fixed
                    For r As Integer = flex.Rows.Fixed To flex.Rows.Count - 1
                        If r = flex.Rows.Count - 1 OrElse (flex.Rows(r).UserData IsNot Nothing AndAlso flex.Rows(r).UserData.ToString() = "*") Then
                            r2 = r
                            _images.Add(flex.CreateImage(r1, c1, r2, c2))
                            _rowOnPage.Add(r2 - r1)
                            _colOnPage.Add(c2 - c1)
                            r1 = r + 1
                        End If
                    Next
                    c1 = c + 1
                End If
            Next
        End Sub
    

    Step 3: Generate PDF Document

    In this step, create a document using C1PrintDocument class of the C1PrintDocument library shipped with ComponentOne WinForms Edition. Use the RenderImage class to add created images to this document and finally, save the PDF document using Export method.

    public void Save(string fileName)
    {
        int perUnitWidth = 250 / _cpp;
        int perUnitHeight = 190 / _rpp;
        // create new C1PrintDocument
        C1PrintDocument c1PrintDocument1 = new C1PrintDocument();
        c1PrintDocument1.AllowNonReflowableDocs = true;
        RenderArea ra1 = new RenderArea();
        // add images to document
        for (int page = 0; page < _images.Count; page++)
        {
            Image img = _images[page] as Image;
            RenderImage ri1 = new RenderImage(img);
            ri1.Width = perUnitWidth * (int)_colOnPage[page] + "mm";
            ri1.Height = perUnitHeight * (int)_rowOnPage[page] + "mm";
            ra1.Children.Add(ri1);
    
        }
        c1PrintDocument1.Body.Children.Add(ra1);
        c1PrintDocument1.Reflow();
        c1PrintDocument1.Export(fileName);
    }
    
        Public Sub Save(ByVal fileName As String)
            Dim perUnitWidth As Integer = 250 / _cpp
            Dim perUnitHeight As Integer = 190 / _rpp
            Dim c1PrintDocument1 As C1PrintDocument = New C1PrintDocument()
            c1PrintDocument1.AllowNonReflowableDocs = True
            Dim ra1 As RenderArea = New RenderArea()
    
            For page As Integer = 0 To _images.Count - 1
                Dim img As Image = TryCast(_images(page), Image)
                Dim ri1 As RenderImage = New RenderImage(img)
                ri1.Width = perUnitWidth * CInt(_colOnPage(page)) & "mm"
                ri1.Height = perUnitHeight * CInt(_rowOnPage(page)) & "mm"
                ra1.Children.Add(ri1)
            Next
            c1PrintDocument1.Body.Children.Add(ra1)
            c1PrintDocument1.Reflow()
            c1PrintDocument1.Export(fileName)
        End Sub
    End Class