zoukankan      html  css  js  c++  java
  • WPF 打印界面(控件)到A4纸

    这次遇到一个需求,就是将整个界面打印在A4纸上。

    需求清楚后,Bing一下关于打印,就找到一个类PrintDialog ,其中两个方法可能会用到:

    特别是public void PrintVisual(Visual visual, string description)可以直接传一个控件就能打印出来了。试了一下后发现,只打印了部分,还有部分没打印出来。

    继续Bing,就是看了一篇关于打印UserControl的文章 ,直接c+v到工程中,很强大,能打印且还分页打印了。但是界面布局变丑了,仔细研究了一下源码,是由于修改了界面的比率和宽度导致的。但是无论我怎么修改,一直没有达到理想的效果。我就想有没有其他的方法,不修改比率和宽度。答案是肯定有的,将整个界面按照一定的比率保存为图片(关于DPI,分辨率的知识,自行百度,因为我说不清楚),然后再打印出来,就可以了。

    代码逻辑如下

    1.初始化一个打印对象

    public class ControlPrint
        {
            //A4纸的尺寸300dpi 的图像的像素是2480×3508
            private const int A4_WIDTH_PIXEL = 2480;
            private const int A4_HEIGTH_PIXEL = 3580;
    
            // 图片 和 界面 dpi比率
            // 通常图片都是300 dpi  而是界面96 dpi(dpi dot per inch)
            private readonly double IMAGE_DPI_SCALE = 300.0 / 96.0;
    
            //标准打印使用 300dpi
            private readonly double PRINT_DPI_X = 300;
            private readonly double PRINT_DPI_Y = 300;
    
            private PrintDialog _printer = null;
    
            public ControlPrint()
            {
                InitPrinter();
            }
    
            private void InitPrinter()
            {
                _printer = new PrintDialog();
                //灰度打印
                _printer.PrintTicket.OutputColor = OutputColor.Grayscale;
            }
             .....
        
    }

    2.打印:截图,将图片放到文档中,打印文档

           ........ 
           /// <summary>
            /// print
            /// </summary>
            /// <param name="control"></param>
            /// <returns></returns>
            public bool Print(FrameworkElement control)
            {
                if (null == control || null == _printer)
                {
                    return false;
                }
    
                try
                {
              //截图
    var bitmapSrc = CaptureControlScreen(control); //图片放在文档里 var fixedDoc = GenerateDocument(bitmapSrc); //打印 _printer.PrintDocument(fixedDoc.DocumentPaginator, "print reprot"); return true; } catch (Exception) { return false; } } .......

    3.截图和创建文档。

            ......
            /// <summary>
            /// control to BitmapSource
            /// https://blogs.msdn.microsoft.com/jaimer/2009/07/03/rendertargetbitmap-tips/
            /// </summary>
            /// <param name="control"></param>
            /// <returns></returns>
            private BitmapSource CaptureControlScreen(Visual control)
            {
                var bounds = VisualTreeHelper.GetDescendantBounds(control);
    
                var rtb = new RenderTargetBitmap((int)(bounds.Width * IMAGE_DPI_SCALE),
                                                      (int)(bounds.Height * IMAGE_DPI_SCALE),
                                                       PRINT_DPI_X, PRINT_DPI_Y,
                                                       PixelFormats.Pbgra32);
    
                var dv = new DrawingVisual();
                using (DrawingContext ctx = dv.RenderOpen())
                {
                    VisualBrush vb = new VisualBrush(control);
                    ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
                }
                rtb.Render(dv);
                return rtb;
            }
    
            /// <summary>
            /// document
            /// </summary>
            /// <param name="bmpSource"></param>
            /// <returns></returns>
            private FixedDocument GenerateDocument(BitmapSource bmpSource)
            {
                if (null == bmpSource)
                {
                    return null;
                }
    var capabilities = _printer.PrintQueue.GetPrintCapabilities(_printer.PrintTicket); //append bitmap to control of image var image = new Image(); image.Source = bmpSource; image.VerticalAlignment = VerticalAlignment.Top; image.HorizontalAlignment = HorizontalAlignment.Center; image.Width = capabilities.PageImageableArea.ExtentWidth; image.Height = capabilities.PageImageableArea.ExtentHeight; //append image to fixedpage var printDocumentPage = new FixedPage(); printDocumentPage.Width = capabilities.PageImageableArea.ExtentWidth; printDocumentPage.Height = capabilities.PageImageableArea.ExtentHeight; printDocumentPage.HorizontalAlignment = HorizontalAlignment.Center; printDocumentPage.Children.Add(image); //append fixedpage to pagecontent var pageContent = new PageContent(); pageContent.HorizontalAlignment = HorizontalAlignment.Center; ((System.Windows.Markup.IAddChild)pageContent).AddChild(printDocumentPage); //append pagecontent to document var fixedDoc = new FixedDocument(); fixedDoc.Pages.Add(pageContent); return fixedDoc; }

    至此就完成了打印界面。需要注意的是,如果界面有滚动条的话,那打印的是滚动条里面的一层grid或者panel,这样才能完整的打印出。

  • 相关阅读:
    C++
    复盘-2018.6.8~2020.6.8
    C++
    C++
    C++
    C++
    Python学习笔记(十)- 面向对象(一)
    SSHException: Error reading SSH protocol banner
    docker 安装mysql
    docker 安装部署
  • 原文地址:https://www.cnblogs.com/hbatjzyb/p/WPF.html
Copyright © 2011-2022 走看看