Export a range as an image without headers and footers

Hello,

We’re trying to export a range of cells as an image using SheetRender. If the user has a header or footer defined then they are displayed in the image that is taken and that is not desired in this case. Other properties like zoom, margins, freeze panes and print titles are easy to save, adjust and reset after taking the image. However this is very difficult to do with headers and footers because there may be image streams to deal with. It would be ideal if the ImageOrPrintOptions class had a IgnoreHeadersAndFooters option to skip rendering the Header and Footer for a screenshot. This seems like a common enough case that the developer should have the option.

Thank you for the consideration.
-Andy

Hi @weissa,

Please check the Class PageSetup, specially the methods setPrintHeadings and clearHeaderFooter ()

@mlyra,

I appreciate the quick reply and I’m aware of these methods. The challenge is that I would like to take a screenshot from a range within the document without breaking the user’s custom headers and footers. While adjusting and resetting other page setup properties like PrintHeadings and Zoom are easy, clearing and then replacing the header and footer is much more complicated.

To save the current header and footer one would need to inspect GetCommands, GetEvenHeader, GetFheader, GetFirstPageHeader and GetPicture for both the header and the footer and for all 6 sections. Then save this information, take the screenshot and reset with all the equivalent Set functions. I’m requesting a feature to ignore headers during a SheetRender operation so that this onerous work can be avoided for just headers & footers.

Thank You,
-Andy

@weissa

Please try ImageOrPrintOptions.OnlyArea option and set it to true. Header and footer will not be output.

Please let us know whether it meets your requirements.

@Peyton.Xu,

This is perfect. I needed the scaling functionality, which is ignored when OnlyArea is set to true, but there are other ways to scale an image.

Below is a working example for others to benefit from. This will allow you to take a picture of a range (without headers and footers) and supports scaling the image.

Usage:

var imageStream = new MemoryStream();    
worksheet.GetPictureOfRange("C2:F15", imageStream, 50) // scaled to 50%

Code:

 public static void GetPictureOfRange(this Worksheet worksheet, string address, Stream stream, int scale)
    {
        if (scale == 0) 
            scale = 100;

        scale = Math.Min(400, Math.Max(10, scale));

        //var saveZoom = worksheet.PageSetup.Zoom;
        var savePrintArea = worksheet.PageSetup.PrintArea;
        var saveLeftMargin = worksheet.PageSetup.LeftMargin;
        var saveRightMargin = worksheet.PageSetup.RightMargin;
        var saveTopMargin = worksheet.PageSetup.TopMargin;
        var saveBottomMargin = worksheet.PageSetup.BottomMargin;

        worksheet.PageSetup.PrintArea = address;
        worksheet.PageSetup.LeftMargin = 0;
        worksheet.PageSetup.RightMargin = 0;
        worksheet.PageSetup.TopMargin = 0;
        worksheet.PageSetup.BottomMargin = 0;
        //worksheet.PageSetup.Zoom = scale;

        SheetRender sr = new SheetRender(worksheet, new ImageOrPrintOptions
        {
            OnePagePerSheet = true,
            ImageType = Aspose.Cells.Drawing.ImageType.Png,
            HorizontalResolution = 200,
            VerticalResolution = 200,
            Transparent = true,
            TextRenderingHint = TextRenderingHint.AntiAlias,
            OnlyArea = true
        });

        if (scale != 100)
        {
            using var imageStream = new MemoryStream();
            sr.ToImage(0, imageStream);
            
            var sourceBitmap = new Bitmap(imageStream);
            var newWidth = (sourceBitmap.Width * scale) / 100;
            var newHeight= (sourceBitmap.Height * scale) / 100;
            var newBitmap = ResizeImage(sourceBitmap, newWidth, newHeight);

            newBitmap.Save(stream, ImageFormat.Png);
            stream.Rewind();
        }
        else
        {
            sr.ToImage(0, stream);
            stream.Rewind();
        }

        //worksheet.PageSetup.Zoom = saveZoom;
        worksheet.PageSetup.PrintArea = savePrintArea;
        worksheet.PageSetup.LeftMargin = saveLeftMargin;
        worksheet.PageSetup.RightMargin = saveRightMargin;
        worksheet.PageSetup.TopMargin = saveTopMargin;
        worksheet.PageSetup.BottomMargin = saveBottomMargin;

    }

    /// <summary>
    /// Resize the image to the specified width and height.
    /// </summary>
    /// <param name="image">The image to resize.</param>
    /// <param name="width">The width to resize to.</param>
    /// <param name="height">The height to resize to.</param>
    /// <returns>The resized image.</returns>
    public static Bitmap ResizeImage(Image image, int width, int height)
    {
        var destRect = new Rectangle(0, 0, width, height);
        var destImage = new Bitmap(width, height);

        destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var graphics = Graphics.FromImage(destImage))
        {
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }

        return destImage;
    }

    public static void Rewind(this Stream s)
    {
        if (s.CanSeek) s.Seek(0, SeekOrigin.Begin);
    }

@weissa

It is good to know that your issue is figured out.
Thanks for sharing your working solution.