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,這樣才能完整的打印出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM