Difference when exporting to PDF and Excel

3 posts, 0 answers
  1. Alexander
    Alexander avatar
    152 posts
    Member since:
    Jun 2012

    Posted 08 Jul 2011 Link to this post

    When calculating width of the cell for export I was surprised when I discovered the following:
    the handling of controls must be different when exporting to PDF and Excel

    protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
     
                if (IsExport)
                {
                    const int charWidth = 10;
                    var gridWidth = 0;
     
                    foreach (GridColumn column in MasterTableView.Columns)
                    {
                        if (column is GridEditableColumn)
                        {
                            var columnWidth = 0;
                            var currentlyExportingTypes = column.CurrentFilterValue.GetTypesFromSeparatedString<DSExportType>();
     
                            if (currentlyExportingTypes.Count > 0 && !currentlyExportingTypes.Contains(_currentlyExportingType.Value) ||
                                column.HeaderText == "#" || column.UniqueName == "checker")
                            {
                                column.Visible = false;
                            }
     
                            if (column.Visible)
                            {
                                var alignmentCssClassPattern = new Regex("\\b(?<alignment>ca|la|ra)\\b");
                                var alignmentCssClassPatternMatch = alignmentCssClassPattern.Match(column.HeaderStyle.CssClass);
     
                                foreach (GridDataItem dataItem in MasterTableView.Items)
                                {
                                    var currentColumnWidth = 0;
                                    if (column is GridTemplateColumn)
                                    {
                                        int labelLengths;
                                        switch (_currentlyExportingType)
                                        {
                                            case DSExportType.Excel:
                                                labelLengths =
                                                    (from label in dataItem[column.UniqueName].Controls.OfType<LiteralControl>().Where(label => !label.Text.StartsWith("\r\n"))
                                                     select label.Text.Length).Sum();
                                                currentColumnWidth = labelLengths * charWidth;
                                                break;
                                            case DSExportType.Pdf:
                                                labelLengths =
                                                    (from label in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<Label>()
                                                     select label.Text.Length).Sum();
                                                var hyperLinkLengths =
                                                    (from hyperLink in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<HyperLink>()
                                                     select hyperLink.Text.Length).Sum();
                                                var imageWidths =
                                                    (from image in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<Image>()
                                                     select image.Width.Value).Sum();
                                                currentColumnWidth = labelLengths * charWidth + hyperLinkLengths * charWidth + Convert.ToInt32(imageWidths);
                                                break;
                                        }
                                    }
                                    else
                                    {
                                        // Only for text types, should be check the type more carefully in common case!
                                        currentColumnWidth = dataItem[column.UniqueName].Text.Length * charWidth;
                                    }
                                    if (columnWidth < currentColumnWidth)
                                    {
                                        columnWidth = currentColumnWidth;
                                    }
                                    if (alignmentCssClassPatternMatch.Success)
                                    {
                                        switch (alignmentCssClassPatternMatch.Groups["alignment"].Value)
                                        {
                                            case "ca":
                                                dataItem[column.UniqueName].Style["text-align"] = "center";
                                                break;
                                            case "ra":
                                                dataItem[column.UniqueName].Style["text-align"] = "right";
                                                break;
                                            default:
                                                dataItem[column.UniqueName].Style["text-align"] = "left";
                                                break;
                                        }
                                    }
                                    dataItem[column.UniqueName].Style.Add("white-space", "nowrap");
                                }
                                foreach (GridHeaderItem headerItem in MasterTableView.GetItems(GridItemType.Header))
                                {
                                    if (alignmentCssClassPatternMatch.Success)
                                    {
                                        switch (alignmentCssClassPatternMatch.Groups["alignment"].Value)
                                        {
                                            case "ca":
                                                headerItem[column.UniqueName].Style["text-align"] = "center";
                                                break;
                                            case "ra":
                                                headerItem[column.UniqueName].Style["text-align"] = "right";
                                                break;
                                            default:
                                                headerItem[column.UniqueName].Style["text-align"] = "left";
                                                break;
                                        }
                                    }
                                }
                                var finalColumnWidth = Math.Max(columnWidth, column.HeaderText.Length * charWidth);
                                column.HeaderStyle.Width = Unit.Pixel(finalColumnWidth);
                                gridWidth += finalColumnWidth;
                            }
                        }
                    }
                    ExportSettings.Pdf.PageWidth = Unit.Pixel(gridWidth + 2 * PdfGridPadding);
                    _currentlyExportingType = null;
                }
            }
    The given method works, but the question is

    why in the case of Excel export there is only LiteralControl within dataItem[column.UniqueName].Controls? Where is the image, for instance? I need different types of controls to properly calculate cell width.

    But when I am on image column - dataItem[image_column_unique_name].Controls also returns me only LiteralControls and no any reference to the used image:

    <telerik:GridTemplateColumn HeaderStyle-CssClass='GridHeaderGreen ra' ItemStyle-CssClass='ra' UniqueName="image_column_unique_name">
        <ItemTemplate><asp:image runat="server" ImageUrl="~/images/something.png" /></ItemTemplate>
    </telerik:GridTemplateColumn>


  2. Daniel
    Admin
    Daniel avatar
    4943 posts

    Posted 15 Jul 2011 Link to this post

    Hello Alexander,

    Indeed, there are differences in the code that exports RadGrid to these formats. Some of the controls are removed before exporting, others are replaced with text or literal controls.
    For example, our Excel export does not support images, CSV is text-based format, ExcelML gets the data directly from the datasource and so on.
    In short, Word and Excel (HTML) formats are nearly identical in terms of code and structure. All other formats are different in one way or another.

    Best regards,
    Daniel
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Alexander
    Alexander avatar
    152 posts
    Member since:
    Jun 2012

    Posted 19 Jul 2011 Link to this post

    For client-side binding i can see IMAGES in exported excel file. Looks like it's just a code limitation: not to be able to export images in server-side grid.

    Please, have a look below at short explanation - what i can see in PreRender event in both cases, after i clicked on export button and loop through

    foreach (GridColumn column in MasterTableView.Columns)
    {
         ....
         foreach (GridDataItem dataItem in MasterTableView.Items)
         {
              ....
              // CHECKING HERE...
         }
    }

    1) client-side binding
    dataItem['image_column'].Controls contains Label controls with text = 'img src="blablabla"...'
    2) server-side binding
    dataItem['image_column'].Controls contains LiteralControl controls with empty text or just tons of separators, tabs, etc: \t\t\t (useful information about image sources is lost)
Back to Top