WPF实战案例-打印
生活随笔
收集整理的這篇文章主要介紹了
WPF实战案例-打印
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在前段時間做了一下打印,因為需要支持的格式比較多,所以wpf能打印的有限分享一下幾種格式的打印(.xls .xlsx .doc .docx .png .jpg .bmp .pdf)
首先為了保證excel和word的格式問題,excel和word是調用的office進行打印的。
獲取所有打印機的方法:
LocalPrintServer print = new LocalPrintServer();var printers = print.GetPrintQueues();foreach (var item in printers){//打印機名稱 item.Name;}?
?
Excel打印。三個參數 :1.打印機名稱? 2要打印的文件路徑+名稱? ?3要打印的sheet頁名稱(可以不寫就打印全部sheet)
static Excel.Application Application { get; set; }public static void PrintExcel(string printName, string fileName, List<string> sheetNames = null){if (Application == null)Application = new Excel.Application();Application.Visible = false;//Application.Calculation = Excel.XlCalculation.xlCalculationManual;var book = Application.Workbooks.Open(fileName);if (sheetNames == null){sheetNames = new List<string>();Excel.Sheets sheets = book.Sheets;for (int i = 1; i <= sheets.Count; i++){Excel.Worksheet workSheet = sheets.Item[i];if (workSheet.Visible != Excel.XlSheetVisibility.xlSheetHidden)sheetNames.Add(workSheet.Name);}}foreach (var item in sheetNames){Excel.Worksheet workSheet = (Excel.Worksheet)book.Worksheets[item];//------------------------打印頁面相關設置--------------------------------workSheet.PageSetup.PaperSize = Excel.XlPaperSize.xlPaperA4;//紙張大小//workSheet.PageSetup.Orientation = Excel.XlPageOrientation.xlLandscape;//頁面橫向workSheet.PageSetup.Zoom = 75; //打印時頁面設置,縮放比例百分之幾workSheet.PageSetup.Zoom = false; //打印時頁面設置,必須設置為false,頁高,頁寬才有效workSheet.PageSetup.FitToPagesWide = 1; //設置頁面縮放的頁寬為1頁寬workSheet.PageSetup.FitToPagesTall = false; //設置頁面縮放的頁高自動//workSheet.PageSetup.LeftHeader = "Nigel";//頁面左上邊的標志//workSheet.PageSetup.CenterFooter = "第 &P 頁,共 &N 頁";//頁面下標workSheet.PageSetup.FirstPageNumber = (int)Excel.Constants.xlAutomatic;workSheet.PageSetup.Order = Excel.XlOrder.xlDownThenOver;workSheet.PageSetup.PrintGridlines = true; //打印單元格網線workSheet.PageSetup.TopMargin = 1.5 / 0.035; //上邊距為2cm(轉換為in)workSheet.PageSetup.BottomMargin = 1.5 / 0.035; //下邊距為1.5cmworkSheet.PageSetup.LeftMargin = 2 / 0.035; //左邊距為2cmworkSheet.PageSetup.RightMargin = 2 / 0.035; //右邊距為2cmworkSheet.PageSetup.CenterHorizontally = true; //文字水平居中//------------------------打印頁面設置結束-------------------------------- workSheet.PrintOutEx(Missing.Value, Missing.Value, Missing.Value, Missing.Value, printName);}//book.PrintOutEx(Missing.Value, Missing.Value, Missing.Value, Missing.Value, printName); //直接打印book.Close(false); //關閉工作空間 }excel有時候關不干凈,貢獻一個強制關閉的方法,可以在excel操作完成后調用:
[DllImport("User32.dll")]public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int Processid);public static void ExcelClose(){if (Application != null){Application.Quit();int iId = 0;IntPtr intptr = new IntPtr(Application.Hwnd);System.Diagnostics.Process p = null;try{GetWindowThreadProcessId(intptr, out iId);p = System.Diagnostics.Process.GetProcessById(iId);if (p != null){p.Kill();p.Dispose();}Application = null;}catch (Exception e){throw e;}}System.GC.Collect();}?
Word打印(打印機名稱,要打印的文件路徑+名稱)
public static void PrintWord(string printName, string fileName){Word.Application appword = new Word.Application();appword.Visible = false;appword.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;Word.Document doc = appword.Documents.Open(fileName);appword.ActivePrinter = printName;doc.PrintOut(true);doc.Close(false);appword.Quit();}圖片打印WPF(支持格式 png jpg bmp)
public static string PrintImage(string printName, string fileName){System.Windows.Controls.PrintDialog dialog = new System.Windows.Controls.PrintDialog();//開始打印var printers = new LocalPrintServer().GetPrintQueues();var selectedPrinter = printers.FirstOrDefault(d => d.Name == printName);if (selectedPrinter == null){return "沒有找到打印機";}dialog.PrintQueue = selectedPrinter;dialog.PrintDocument(new TestDocumentPaginator(new BitmapImage(new Uri(fileName))), "Image");return "";} public class TestDocumentPaginator : DocumentPaginator{#region 字段private Size _pageSize;private ImageSource image;#endregion#region 構造public TestDocumentPaginator(BitmapImage img){image = img;//我們使用A3紙張大小var pageMediaSize = LocalPrintServer.GetDefaultPrintQueue().GetPrintCapabilities().PageMediaSizeCapability.FirstOrDefault(x => x.PageMediaSizeName == PageMediaSizeName.ISOA4);if (pageMediaSize != null){_pageSize = new Size((double)pageMediaSize.Width, (double)pageMediaSize.Height);}}#endregion#region 重寫/// <summary>/// /// </summary>/// <param name="pageNumber">打印頁是從0開始的</param>/// <returns></returns>public override DocumentPage GetPage(int pageNumber){var visual = new DrawingVisual();using (DrawingContext dc = visual.RenderOpen()){double imgWidth = 0;double imgHeight = 0;if (image.Height > _pageSize.Height){double h = _pageSize.Height / image.Height;imgWidth = image.Width * h;imgHeight = image.Height * h;}if (image.Width > _pageSize.Width){double w = _pageSize.Width / image.Width;imgWidth = image.Width * w;imgHeight = image.Height * w;}if (image.Width < _pageSize.Width && image.Height < _pageSize.Height){double h = _pageSize.Height / image.Height;double w = _pageSize.Width / image.Width;if (h > w){imgWidth = image.Width * w;imgHeight = image.Height * w;}else{imgWidth = image.Width * h;imgHeight = image.Height * h;}}double left = Math.Abs((_pageSize.Width - imgWidth) <= 0 ? 2 : (_pageSize.Width - imgWidth)) / 2;double top = Math.Abs((_pageSize.Height - imgHeight) <= 0 ? 2 : (_pageSize.Height - imgHeight)) / 2;dc.DrawImage(image, new Rect(left, top, imgWidth, imgHeight));}return new DocumentPage(visual, _pageSize, new Rect(_pageSize), new Rect(_pageSize));}public override bool IsPageCountValid{get{return true;}}public override Size PageSize{get{return _pageSize;}set{_pageSize = value;}}public override IDocumentPaginatorSource Source{get{return null;}}public override int PageCount{get{return 1;}}#endregion} TestDocumentPaginator內部的重寫方法是計算將圖片全部居中顯示。關于圖片打印多說一句:在之前我是使用image加載圖片,然后通過PrintVisual打印控件的方式打印的,但是這種方式我發現在win7機器上打印出來的是空白紙張,還沒明白是為什么,所以就用這種方式了。
PDF打印(這是調用windows api去打印,不需要亂起八糟的第三方): // Structure and API declarions:[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]public class DOCINFOA{[MarshalAs(UnmanagedType.LPStr)]public string pDocName;[MarshalAs(UnmanagedType.LPStr)]public string pOutputFile;[MarshalAs(UnmanagedType.LPStr)]public string pDataType;}[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool ClosePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndDocPrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);// SendBytesToPrinter()// When the function is given a printer name and an unmanaged array// of bytes, the function sends those bytes to the print queue.// Returns true on success, false on failure.public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount){Int32 dwError = 0, dwWritten = 0;IntPtr hPrinter = new IntPtr(0);DOCINFOA di = new DOCINFOA();bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "My C#.NET RAW Document";di.pDataType = "RAW";// Open the printer.if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)){// Start a document.if (StartDocPrinter(hPrinter, 1, di)){// Start a page.if (StartPagePrinter(hPrinter)){// Write your bytes.bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);EndPagePrinter(hPrinter);}EndDocPrinter(hPrinter);}ClosePrinter(hPrinter);}// If you did not succeed, GetLastError may give more information// about why not.if (bSuccess == false){dwError = Marshal.GetLastWin32Error();}return bSuccess;}public static bool SendFileToPrinter(string szPrinterName, string szFileName){// Open the file.FileStream fs = new FileStream(szFileName, FileMode.Open);// Create a BinaryReader on the file.BinaryReader br = new BinaryReader(fs);// Dim an array of bytes big enough to hold the file's contents.Byte[] bytes = new Byte[fs.Length];bool bSuccess = false;// Your unmanaged pointer.IntPtr pUnmanagedBytes = new IntPtr(0);int nLength;nLength = Convert.ToInt32(fs.Length);// Read the contents of the file into the array.bytes = br.ReadBytes(nLength);// Allocate some unmanaged memory for those bytes.pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);// Copy the managed byte array into the unmanaged array.Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);// Send the unmanaged bytes to the printer.bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);// Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(pUnmanagedBytes);return bSuccess;}public static bool SendStringToPrinter(string szPrinterName, string szString){IntPtr pBytes;Int32 dwCount;// How many characters are in the string?dwCount = szString.Length;// Assume that the printer is expecting ANSI text, and then convert// the string to ANSI text.pBytes = Marshal.StringToCoTaskMemAnsi(szString);// Send the converted ANSI string to the printer. SendBytesToPrinter(szPrinterName, pBytes, dwCount);Marshal.FreeCoTaskMem(pBytes);return true;} public static void PrintPDF(string printName, string fileName){SendFileToPrinter(printName, fileName);}
以上就是wpf常用的打印,目前看起來格式還是可以達到要求的,更多技術討論請關注頁面下方的qq群。
轉載于:https://www.cnblogs.com/BeiJing-Net-DaiDai/p/10243072.html
總結
以上是生活随笔為你收集整理的WPF实战案例-打印的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: swagger报错No handler
- 下一篇: 抽象工厂模式(JAVA反射)