This is a migrated thread and some comments may be shown as answers.

ExportCellFormatting and PDF

7 Answers 307 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tim
Top achievements
Rank 1
Tim asked on 30 Jan 2012, 10:55 PM
I am trying to horizontally align specific cells when exporting the same as their ItemStyle in the markup.  I've followed several links and have it working for Excel but PDF does not.

The ExportCellFormatting event handler does not appear to fire when exporting to PDF like it does for Excel.  I believe this event is supposed to be a replacement for the deprecated ExcelExportCellFormatting event, but I would think based off the name and the deprecation of its predecessor that this should fire for PDFs as well.

ExportCellFormatting is the only event that I've found thus far where the cell's HorizontalAlign is set (off the e.FormattedColumn.ItemStyle) -- if I check the cell's HorizontalAlign in either the ItemCreated or ItemCommand event handlers it is always HorizontalAlign.NotSet.  The PdfExporting event only exposes the raw HTML, which I can manipulate, but that is tedious.

I am able to get basic formatting to occur for PDF so long as it isn't related to checking something set in the markup.  For example, I can detect whether the ItemType is an Item or AlternatingItem and set the inline style accordingly for alternating rows, and set the basic font, font size, and header formatting.

How can I format what's exported to PDF based on the formatted columns, specifically the horizontal alignment of individual cells?  Below are code samples of what I have working so far.

    <jha:RadGrid ID="grdVendors" runat="server" DataSourceID="odsVendors"
        OnItemDataBound="grdVendors_ItemDataBound" OnItemCommand="grdVendors_ItemCommand"
        OnExportCellFormatting="grdVendors_ExportCellFormatting" OnItemCreated="grdVendors_ItemCreated" OnPdfExporting="grdVendors_PdfExporting">
        <MasterTableView DataKeyNames="VendorID">
            <Columns>
                <telerik:GridBoundColumn HeaderText="ID" DataField="VendorID" Visible="false" />
                <telerik:GridBoundColumn HeaderText="First Name" DataField="FirstName" />
                <telerik:GridBoundColumn HeaderText="Last Name" DataField="LastName" />
                <telerik:GridBoundColumn HeaderText="City" DataField="City" />
                <telerik:GridBoundColumn HeaderText="State" DataField="State" ItemStyle-HorizontalAlign="Center" />
                <telerik:GridBoundColumn UniqueName="CreatedOn" HeaderText="Created On" DataField="CreatedDateTime"
                    DataFormatString="{0:MM/dd/yyyy}" ItemStyle-HorizontalAlign="Right" />
            </Columns>
        </MasterTableView>
    </jha:RadGrid>

protected void grdVendors_ItemCommand(object sender, GridCommandEventArgs e)
{
    switch (e.CommandName)
    {
        case RadGrid.ExportToExcelCommandName:
        case RadGrid.ExportToPdfCommandName:
            grdVendors.CssClass = "export";
            string title = "Foo";
 
            GridExportSettings settings = grdVendors.ExportSettings;
            settings.ExportOnlyData = true;
            settings.OpenInNewWindow = true;
            settings.IgnorePaging = true;
            settings.HideStructureColumns = true;
            settings.FileName = string.Format("{0} {1:yyyy-MM-dd}", title, DateTime.Now);
 
            // PDF
            settings.Pdf.DefaultFontFamily = "Tahoma";
            settings.Pdf.PageTitle = title;
            settings.Pdf.Title = title;
            settings.Pdf.AllowPrinting = true;
            settings.Pdf.AllowAdd = false;
            settings.Pdf.AllowCopy = true;
            settings.Pdf.AllowModify = false;
            settings.Pdf.PaperSize = GridPaperSize.A4;
            settings.Pdf.PageHeight = Unit.Parse("210mm");
            settings.Pdf.PageWidth = Unit.Parse("297mm");
            settings.Pdf.PageTopMargin = Unit.Parse("20mm");
            settings.Pdf.PageHeaderMargin = Unit.Parse("10mm");
            settings.Pdf.PageBottomMargin = Unit.Parse("10mm");
            settings.Pdf.PageLeftMargin = Unit.Parse("10mm");
            settings.Pdf.PageRightMargin = Unit.Parse("10mm");
            break;
    }
}
 
protected void grdVendors_ExportCellFormatting(object sender, ExportCellFormattingEventArgs e)
{
    /// Never fires when exporting to PDF
    switch (e.FormattedColumn.ItemStyle.HorizontalAlign)
    {
        case HorizontalAlign.Left:
            e.Cell.Style["text-align"] = "left";
            break;
        case HorizontalAlign.Center:
            e.Cell.Style["text-align"] = "center";
            break;
        case HorizontalAlign.Right:
            e.Cell.Style["text-align"] = "right";
            break;
    }
 
    if (e.FormattedColumn.UniqueName == "PostalCode")
        e.Cell.Style["mso-number-format"] = @"\@";
}
 
protected void grdVendors_ItemCreated(object sender, GridItemEventArgs e)
{
    if (grdVendors.CssClass.Contains("export"))
    {
        if (e.Item is GridDataItem)
        {
            foreach (TableCell cell in e.Item.Cells)
            {
                if (e.Item.ItemType == GridItemType.AlternatingItem)
                    cell.Style["background-color"] = "#E6EFF7";
                else
                    cell.Style["background-color"] = "#FFFFFF";
            }
        }
        else if (e.Item is GridHeaderItem)
        {         
            Table table = e.Item.Parent.Parent as Table;
            table.Style["font-family"] = "Tahoma";
            table.Style["font-size"] = "8pt";
 
            foreach (TableCell cell in e.Item.Cells)
            {
                cell.Style["border-color"] = "#FFFFFF";
                cell.Style["background-color"] = "#EEEEEE";
                cell.Style["text-align"] = "left";
                cell.Style["color"] = "#274777";
                cell.Style["font-weight"] = "bold";
            }
        }
    }
}


Regards,
Tim

7 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 31 Jan 2012, 04:53 AM
Hello,

One suggestion is you can try with OnPdfExporting event. ExportCellFormatting  is mainly used for Excel exporting. Also take a look into the following documentation.
PDF export


Thanks,
Princy.
0
Tim
Top achievements
Rank 1
answered on 31 Jan 2012, 02:46 PM
Thanks for your input, Princy.  As I mentioned in my original post, I have already tried using the OnPdfExport event and all it exposes is the raw HTML, which is tedious to work with and I don't have access to the specific column/cell reference to determine alignments.

Thanks for the link.  I had already looked through that as well.  That's where I found the trick to set a Boolean on ItemCommand when exporting and check that Boolean on ItemCreated so that export-specific code doesn't fire during the normal grid load.  That page is also where I found several tips for some of the other PDF settings for landscape orientation and whatnot.  Unfortunately it doesn't cover what I'm looking for.

Any other ideas?

Regards,
Tim
0
Andrey
Telerik team
answered on 02 Feb 2012, 04:45 PM
Hi,

As you already noticed the ExportCellFormatting event is not fired when you are exporting to PDF, this is true because this event is not relevant in this case. It main usage is when exporting to Word/Excel.

You could do the required modifications in the ItemCreated event of RadGrid, like shown in this online demo.

Give this approach a try and check whether you are getting the expected behavior.

Regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Tim
Top achievements
Rank 1
answered on 02 Feb 2012, 04:56 PM
Hi Andrey,

Thanks for replying to my question.  I actually had already looked through that example and it handles some of what I needed but as I mentioned in my original post, detecting the horizontal alignment of a grid column always returns "not set" in the ItemCreated event handler, whereas in the ExportCellFormatting I can get the e.FormattedColumn and it knows the horizontal alignment.

In the Sushi PDF example it sets the inline style alignment fine because every column is centered, whereas in my grids certain columns are aligned left, others centered, and others aligned right.

Setting the inline styles is not my problem; I need to be able to DETECT what the alignment (or other properties like that) are on the grid for each column/cell/whatever and then set its inline style based on that.

Any other ideas on how I could detect that within the ItemCreated or some other event that PDF exporting would catch?

Regards,
Tim

0
Accepted
Andrey
Telerik team
answered on 03 Feb 2012, 04:11 PM
Hello,

If you want to check for the column's horizontal align, you could do so by iterating through the columns collection of RadGrid in PreRender event. At this time the property will be initialized and you will be able to get its real value. You could use the following code:

protected void RadGrid1_PreRender(object sender, EventArgs e)
    {
        foreach (GridColumn column in RadGrid1.MasterTableView.Columns)
        {
            if (column.ItemStyle.HorizontalAlign == HorizontalAlign.Left)
            {
            }
        }
    }

Give this approach a try and check whether this is the desired behavior.

Kind regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Tim
Top achievements
Rank 1
answered on 03 Feb 2012, 09:30 PM
That works; thanks Andrey!

I'm not a big fan of having to use nested loops but it does the trick.  And since I'm checking to make sure I'm exporting (by setting the CSS class of "export" when the ItemCommand event fires for the appropriate command names), it only processes the loops during the export, which I'm OK with taking a little longer if needed.

protected void grdVendors_PreRender(object sender, EventArgs e)
{
    if (grdVendors.CssClass.Contains("export"))
    {
        foreach (GridDataItem item in grdVendors.MasterTableView.Items)
        {
            foreach (GridColumn column in grdVendors.MasterTableView.Columns)
            {
                switch (column.ItemStyle.HorizontalAlign)
                {
                    case HorizontalAlign.Left:
                        item.Cells[column.OrderIndex].Style["text-align"] = "left";
                        break;
                    case HorizontalAlign.Center:
                        item.Cells[column.OrderIndex].Style["text-align"] = "center";
                        break;
                    case HorizontalAlign.Right:
                        item.Cells[column.OrderIndex].Style["text-align"] = "right";
                        break;
                }
            }
        }
    }
}
0
Andrey
Telerik team
answered on 06 Feb 2012, 03:50 PM
Hi,

Yes, it is not so good to have nested loops, but in this case it won't lead to a significant slow-down, especially if Paging feature of RadGrid is enabled. Thus you will iterate through the items in the current page only.

I think that the overall slow-down of the site won't exceed 1s per postback.

Kind regards,
Andrey
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
Grid
Asked by
Tim
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
Tim
Top achievements
Rank 1
Andrey
Telerik team
Share this question
or