办公超实用利器系列-批量打印
背景
1.经常会遇到打印某个人的A\B\C文档,包含Word、Excel、图片三种内容,有些需要单面打印,有些需要双面打印,如果打开文件去打印很麻烦,尤其是需要批量的时候。
2.单双面打印的设定代码网上很多,但最后还是在msdn上找到确实能用的,之前也发出来了。
功能
1、设定打印顺序、数量、内容
2.设定绑定的数据源
3、打印
关键源码
1.打印规则
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Text.RegularExpressions; using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.Drawing.Printing; using System.Runtime.InteropServices; using System.Diagnostics; using WORD = Microsoft.Office.Interop.Word; using EXCEL = Microsoft.Office.Interop.Excel; using REP = DAL.FILEPRINT.Repository; using FrameWork; using System.Drawing; using System.Drawing.Printing; namespace DAL.FILEPRINT { public class ActionModual { /// <summary> /// 建立映射打印规则 /// </summary> /// <param name="druplex"></param> /// <returns></returns> public static Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>> InitMappingPrintStrategy(Dictionary<bool, Action<PrintDocument>> druplex, PrintDocument pd, WORD.Application wordApp, EXCEL.Application excelApp) { Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>> format = new Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>>(); #region "word" format.Add("word", new Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.WordAction wordRec = action as REP.WordAction; //双面设置 druplex[wordRec.IsDruplex].Invoke(pd); //直接打印 if (wordRec.IsDirectPrint) { //检查文件夹是否固定 if (wordRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + wordRec.JoinName + ".doc"; if (File.Exists(fileName)) { PrintWord(fileName, pd, wordRec, wordApp); } } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(wordRec.JoinName)) { string fileName = folderPath + wordRec.JoinName + ".doc"; if (File.Exists(fileName)) { PrintWord(fileName, pd, wordRec, wordApp); } } else { if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.doc").ToList(); foreach (var file in matchFiles) { PrintWord(file, pd, wordRec, wordApp); } } } } else { //不直接打印,通过挂接 //找出文件夹和对应所有文件 if (wordRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, wordRec.JoinName, "*.doc", rowRec); foreach (var file in matchFiles) { PrintWord(file, pd, wordRec, wordApp); } } })); #endregion #region "excel" format.Add("excel", new Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.ExcelAction excelRec = action as REP.ExcelAction; //双面设置 druplex[excelRec.IsDruplex].Invoke(pd); //直接打印 if (excelRec.IsDirectPrint) { //检查文件夹是否固定 if (excelRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + excelRec.JoinName + ".xls"; if (File.Exists(fileName)) { PrintExcel(fileName, pd, excelRec, excelApp); } } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(excelRec.JoinName)) { string fileName = folderPath + excelRec.JoinName + ".xls"; if (File.Exists(fileName)) { PrintExcel(fileName, pd, excelRec, excelApp); } } else { if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.xls").ToList(); foreach (var file in matchFiles) { PrintExcel(file, pd, excelRec, excelApp); } } } } else { //不直接打印,通过挂接 //找出文件夹和对应所有文件 if (excelRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, excelRec.JoinName, "*.xls", rowRec); foreach (var file in matchFiles) { PrintExcel(file, pd, excelRec, excelApp); } } })); #endregion #region "img" format.Add("img", new Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.ImgAction imgRec = action as REP.ImgAction; //双面设置 druplex[imgRec.IsDruplex].Invoke(pd); if (imgRec.IsDirectPrint) { #region 直接打印 //检查文件夹是否固定 if (imgRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + imgRec.JoinName + ".jpg"; if (File.Exists(fileName)) { string[] file = { fileName }; PrintImage(file, pd, imgRec); } } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(imgRec.JoinName)) { string fileName = folderPath + imgRec.JoinName + ".jpg"; if (File.Exists(fileName)) { string[] file = { fileName }; PrintImage(file, pd, imgRec); } } else { if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.jpg").ToList(); PrintImage(matchFiles.ToArray(), pd, imgRec); } } #endregion } else { #region 不直接打印,通过挂接 //找出文件夹和对应所有文件 if (imgRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, imgRec.JoinName, "*.jpg", rowRec); if (matchFiles.Count != 0) { PrintImage(matchFiles.ToArray(), pd, imgRec); } #endregion } })); #endregion return format; } /// <summary> /// 建立直接打印规则 /// </summary> /// <param name="druplex"></param> /// <returns></returns> public static Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting>> InitDirectPrintStrategy(Dictionary<bool, Action<PrintDocument>> druplex, PrintDocument pd, WORD.Application wordApp, EXCEL.Application excelApp) { Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting>> format = new Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting>>(); #region "word" format.Add("word", new Action<string, REP.IAction, REP.GeneralSetting>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.WordAction wordRec = action as REP.WordAction; //双面设置 druplex[wordRec.IsDruplex].Invoke(pd); //直接打印 if (wordRec.IsDirectPrint) { //检查文件夹是否固定 if (wordRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + wordRec.JoinName + ".doc"; PrintWord(fileName, pd, wordRec, wordApp); } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(wordRec.JoinName)) { string fileName = folderPath + wordRec.JoinName + ".doc"; PrintWord(fileName, pd, wordRec, wordApp); } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.doc").ToList(); foreach (var file in matchFiles) { PrintWord(file, pd, wordRec, wordApp); } } } } })); #endregion #region "excel" format.Add("excel", new Action<string, REP.IAction, REP.GeneralSetting>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.ExcelAction excelRec = action as REP.ExcelAction; //双面设置 druplex[excelRec.IsDruplex].Invoke(pd); //直接打印 if (excelRec.IsDirectPrint) { //检查文件夹是否固定 if (excelRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + excelRec.JoinName + ".xls"; PrintExcel(fileName, pd, excelRec, excelApp); } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(excelRec.JoinName)) { string fileName = folderPath + excelRec.JoinName + ".xls"; PrintExcel(fileName, pd, excelRec, excelApp); } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.xls").ToList(); foreach (var file in matchFiles) { PrintExcel(file, pd, excelRec, excelApp); } } } } })); #endregion #region "img" format.Add("img", new Action<string, REP.IAction, REP.GeneralSetting>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.ImgAction imgRec = action as REP.ImgAction; //双面设置 druplex[imgRec.IsDruplex].Invoke(pd); //直接打印 if (imgRec.IsDirectPrint) { //检查文件夹是否固定 if (imgRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + imgRec.JoinName + ".jpg"; string[] file = { fileName }; PrintImage(file, pd, imgRec); } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(imgRec.JoinName)) { string fileName = folderPath + imgRec.JoinName + ".jpg"; string[] file = { fileName }; PrintImage(file, pd, imgRec); } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.jpg").ToList(); if (matchFiles.Count != 0) { PrintImage(matchFiles.ToArray(), pd, imgRec); } } } } })); #endregion return format; } /// <summary> /// 建立单双面规则 /// </summary> /// <returns></returns> public static Dictionary<bool, Action<PrintDocument>> InitDruplexStrategy() { Dictionary<bool, Action<PrintDocument>> format = new Dictionary<bool, Action<PrintDocument>>(); #region "double" format.Add(true, new Action<PrintDocument>( (PrintDocument pd) => { MyDuplexSettings.DuplexSettings ds = new MyDuplexSettings.DuplexSettings(); string err = string.Empty; ds.SetPrinterDuplex(pd.PrinterSettings.PrinterName, 2, out err); })); #endregion #region "single" format.Add(false, new Action<PrintDocument>( (PrintDocument pd) => { MyDuplexSettings.DuplexSettings ds = new MyDuplexSettings.DuplexSettings(); string err = string.Empty; ds.SetPrinterDuplex(pd.PrinterSettings.PrinterName, 1, out err); })); #endregion return format; } /// <summary> /// 建立冷却规则 /// </summary> /// <returns></returns> public static Dictionary<string, Action<REP.AdvanceSetting>> InitCoolStrategy() { Dictionary<string, Action<REP.AdvanceSetting>> format = new Dictionary<string, Action<REP.AdvanceSetting>>(); #region "word" format.Add("word", new Action<REP.AdvanceSetting>( (REP.AdvanceSetting advRec) => { TimeSpan ts = new TimeSpan(0, 0, 0, int.Parse(advRec.WordCoolSec), int.Parse(advRec.WordCoolMilSec)); System.Threading.Thread.Sleep(ts); })); #endregion #region "excel" format.Add("excel", new Action<REP.AdvanceSetting>( (REP.AdvanceSetting advRec) => { TimeSpan ts = new TimeSpan(0, 0, 0, int.Parse(advRec.ExcelCoolSec), int.Parse(advRec.ExcelCoolMilSec)); System.Threading.Thread.Sleep(ts); })); #endregion #region "img" format.Add("img", new Action<REP.AdvanceSetting>( (REP.AdvanceSetting advRec) => { TimeSpan ts = new TimeSpan(0, 0, 0, int.Parse(advRec.ImgCoolSec), int.Parse(advRec.ImgCoolMilSec)); System.Threading.Thread.Sleep(ts); })); #endregion return format; } /// <summary> /// 建立映射打印计数规则 /// </summary> /// <param name="druplex"></param> /// <returns></returns> public static Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>> InitMappingCalStrategy() { Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>> format = new Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>>(); #region "word" format.Add("word", new Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.WordAction wordRec = action as REP.WordAction; //直接打印 if (wordRec.IsDirectPrint) { //检查文件夹是否固定 if (wordRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + wordRec.JoinName + ".doc"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(wordRec.JoinName)) { string fileName = folderPath + wordRec.JoinName + ".doc"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.doc").ToList(); return matchFiles.Count; } } } else { //不直接打印,通过挂接 //找出文件夹和对应所有文件 if (wordRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, wordRec.JoinName, "*.doc", rowRec); return matchFiles.Count; } })); #endregion #region "excel" format.Add("excel", new Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.ExcelAction excelRec = action as REP.ExcelAction; //直接打印 if (excelRec.IsDirectPrint) { //检查文件夹是否固定 if (excelRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + excelRec.JoinName + ".xls"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(excelRec.JoinName)) { string fileName = folderPath + excelRec.JoinName + ".xls"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.xls").ToList(); return matchFiles.Count; } } } else { //不直接打印,通过挂接 //找出文件夹和对应所有文件 if (excelRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, excelRec.JoinName, "*.xls", rowRec); return matchFiles.Count; } })); #endregion #region "img" format.Add("img", new Func<string, REP.IAction, REP.GeneralSetting, REP.RowRecord, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec, REP.RowRecord rowRec) => { REP.ImgAction imgRec = action as REP.ImgAction; if (imgRec.IsDirectPrint) { #region 直接打印 //检查文件夹是否固定 if (imgRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + imgRec.JoinName + ".jpg"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(imgRec.JoinName)) { string fileName = folderPath + imgRec.JoinName + ".jpg"; if (File.Exists(fileName)) { return 1; } else { return 0; } } else { if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Directory.GetFiles(folderPath, "*.jpg").ToList(); return matchFiles.Count; } } #endregion } else { #region 不直接打印,通过挂接 //找出文件夹和对应所有文件 if (imgRec.isFixedFile) { folderPath = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\"; } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; } if (!Directory.Exists(folderPath)) { return 0; } List<string> matchFiles = Common.GetMatchFilesByRegex(folderPath, imgRec.JoinName, "*.jpg", rowRec); return matchFiles.Count; #endregion } })); #endregion return format; } /// <summary> /// 建立直接打印计数规则 /// </summary> /// <param name="druplex"></param> /// <returns></returns> public static Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, int>> InitDirectCalStrategy() { Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, int>> format = new Dictionary<string, Func<string, REP.IAction, REP.GeneralSetting, int>>(); #region "word" format.Add("word", new Func<string, REP.IAction, REP.GeneralSetting, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.WordAction wordRec = action as REP.WordAction; //直接打印 if (wordRec.IsDirectPrint) { //检查文件夹是否固定 if (wordRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + wordRec.JoinName + ".doc"; return 1; } else { folderPath = folderPath + "\\" + wordRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(wordRec.JoinName)) { string fileName = folderPath + wordRec.JoinName + ".doc"; return 1; } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.doc").ToList(); return matchFiles.Count; } } } else { return 0; } })); #endregion #region "excel" format.Add("excel", new Func<string, REP.IAction, REP.GeneralSetting, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.ExcelAction excelRec = action as REP.ExcelAction; //直接打印 if (excelRec.IsDirectPrint) { //检查文件夹是否固定 if (excelRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + excelRec.JoinName + ".xls"; return 1; } else { folderPath = folderPath + "\\" + excelRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(excelRec.JoinName)) { string fileName = folderPath + excelRec.JoinName + ".xls"; return 1; } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.xls").ToList(); return matchFiles.Count; } } } else { return 0; } })); #endregion #region "img" format.Add("img", new Func<string, REP.IAction, REP.GeneralSetting, int>( (string folderPath, REP.IAction action, REP.GeneralSetting genRec) => { REP.ImgAction imgRec = action as REP.ImgAction; //直接打印 if (imgRec.IsDirectPrint) { //检查文件夹是否固定 if (imgRec.isFixedFile) { string fileName = AppDomain.CurrentDomain.BaseDirectory + @"\固定文件\" + imgRec.JoinName + ".jpg"; return 1; } else { folderPath = folderPath + "\\" + imgRec.FolderName + "\\"; //检查是否固定文件名 if (!string.IsNullOrEmpty(imgRec.JoinName)) { string fileName = folderPath + imgRec.JoinName + ".jpg"; return 1; } else { List<string> matchFiles = Directory.GetFiles(folderPath, "*.jpg").ToList(); return matchFiles.Count; } } } else { return 0; } })); #endregion return format; } #region 打印函数 public static void PrintExcel(string excelFileName, PrintDocument pd, REP.ExcelAction acRec, EXCEL.Application excelApp) { object Missing = System.Reflection.Missing.Value; EXCEL.Workbook workBook = excelApp.Workbooks.Open(excelFileName, null, true); object[] parameters = null; try { parameters = new object[9]; if (acRec.IsAllPage) { parameters[0] = Missing;//from parameters[1] = Missing;//TO } else { parameters[0] = int.Parse(acRec.SPage);//from parameters[1] = int.Parse(acRec.EPage);//TO } parameters[2] = 1;//COPIES parameters[3] = Missing;//PREVIEW parameters[4] = pd.PrinterSettings.PrinterName;//PRINTER parameters[5] = Missing;//PRINTTOFILE parameters[6] = true;//COLLATE parameters[7] = Missing;//FILENAME parameters[8] = Missing;//IGNOREAREA workBook.PrintOutEx( parameters[0], parameters[1], parameters[2], parameters[3], parameters[4], parameters[5], parameters[6], parameters[7], parameters[8]); } catch (Exception ex) { throw ex; } finally { if (workBook != null) { COMExcelTool.ReleaseComObj(workBook); Marshal.FinalReleaseComObject(workBook); workBook = null; } } } public static void PrintWord(string FileName, PrintDocument pd, REP.WordAction acRec, WORD.Application objApp) { object missing = System.Reflection.Missing.Value; object objFileName = FileName; objApp.ActivePrinter = pd.PrinterSettings.PrinterName; WORD.Document objDoc = null; try { objDoc = FrameWork.WordTool.OpenWord(objApp, FileName); objDoc.Activate(); object copies = "1"; object pages = ""; object range = WORD.WdPrintOutRange.wdPrintFromTo; if (acRec.IsAllPage) { range = WORD.WdPrintOutRange.wdPrintAllDocument; } object items = WORD.WdPrintOutItem.wdPrintDocumentContent; object pageType = WORD.WdPrintOutPages.wdPrintAllPages; object oTrue = true; object oFalse = false; object oFrom = !acRec.IsAllPage ? int.Parse(acRec.SPage) : missing; object oTo = !acRec.IsAllPage ? int.Parse(acRec.EPage) : missing; objApp.Options.PrintOddPagesInAscendingOrder = true; objApp.Options.PrintEvenPagesInAscendingOrder = true; if (acRec.IsAllPage) { objDoc.PrintOut( ref oTrue, ref oFalse, ref range, ref missing, ref missing, ref missing, ref items, ref copies, ref pages, ref pageType, ref oFalse, ref oTrue, ref missing, ref oFalse, ref missing, ref missing, ref missing, ref missing); } else { objDoc.PrintOut( ref oTrue, ref oFalse, ref range, ref missing, ref oFrom, ref oTo, ref items, ref copies, ref pages, ref pageType, ref oFalse, ref oTrue, ref missing, ref oFalse, ref missing, ref missing, ref missing, ref missing); } } catch (Exception ex) { throw ex; } finally { if (objDoc != null) { Marshal.ReleaseComObject(objDoc); Marshal.FinalReleaseComObject(objDoc); objDoc = null; } } } public static void PrintImage(string[] FileName, PrintDocument pd2, REP.ImgAction imgRec) { PrintDocument pd = new PrintDocument(); pd.PrinterSettings.PrinterName = pd2.PrinterSettings.PrinterName; pd.DocumentName = imgRec.ActionName; int iCountNm = 0; //是否双面打印 if (imgRec.IsDruplex) { pd.PrinterSettings.Duplex = Duplex.Vertical; } else { pd.PrinterSettings.Duplex = Duplex.Simplex; } //打印 switch (imgRec.PrintType) { case "铺满": pd.PrintPage += (_, e) => { var img = System.Drawing.Image.FromFile(FileName[iCountNm]); e.Graphics.DrawImage(img, 20, 20, e.PageSettings.PrintableArea.Width, e.PageSettings.PrintableArea.Height); if (iCountNm == FileName.Length - 1) { e.HasMorePages = false; } else { e.HasMorePages = true; } iCountNm++; }; break; case "中心尺寸": pd.PrintPage += (_, e) => { var img = System.Drawing.Image.FromFile(FileName[iCountNm]); int iWidth = 450; double hFactor = iWidth / (double)img.Width; int iHeight = Convert.ToInt32(img.Height * hFactor); Rectangle Rect = new Rectangle(180, 350, iWidth, iHeight); e.Graphics.DrawImage(img, Rect); if (iCountNm == FileName.Length - 1) { e.HasMorePages = false; iCountNm = 0; } else { e.HasMorePages = true; iCountNm++; } }; break; case "自定义": pd.PrintPage += (_, e) => { var img = System.Drawing.Image.FromFile(FileName[iCountNm]); int iWidth = int.Parse(imgRec.Width); double hFactor = iWidth / (double)img.Width; int iHeight = Convert.ToInt32(img.Height * hFactor); Rectangle Rect = new Rectangle(int.Parse(imgRec.Left), int.Parse(imgRec.Top), iWidth, iHeight); e.Graphics.DrawImage(img, Rect); if (iCountNm == FileName.Length - 1) { e.HasMorePages = false; } else { e.HasMorePages = true; } iCountNm++; }; break; } pd.Print(); } #endregion #region 获取、设置默认打印机 [DllImport("Winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool SetDefaultPrinter(string printerName); [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref int pcchBuffer); public static string GetDefaultPrinter() { const int ERROR_FILE_NOT_FOUND = 2; const int ERROR_INSUFFICIENT_BUFFER = 122; int pcchBuffer = 0; if (GetDefaultPrinter(null, ref pcchBuffer)) { return null; } int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER) { StringBuilder pszBuffer = new StringBuilder(pcchBuffer); if (GetDefaultPrinter(pszBuffer, ref pcchBuffer)) { return pszBuffer.ToString(); } lastWin32Error = Marshal.GetLastWin32Error(); } if (lastWin32Error == ERROR_FILE_NOT_FOUND) { return null; } throw new NotFiniteNumberException(); } #endregion } }
2.打印函数
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.ComponentModel; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; using WORD = Microsoft.Office.Interop.Word; using EXCEL = Microsoft.Office.Interop.Excel; using System.Drawing; using System.Drawing.Printing; using FrameWork; using REP = DAL.FILEPRINT.Repository; namespace DAL.FILEPRINT { public class PrintModual { public static void PrintByRowRecs(PrintDocument pd, List<REP.IAction> acRecs, REP.GeneralSetting genRec, REP.AdvanceSetting advRec, List<REP.RowRecord> rowRecs, string folderPath, BackgroundWorker bWork) { #region 清理环境 Process[] xlsProcess = Process.GetProcessesByName("EXCEL"); for (int i = 0; i < xlsProcess.Length; i++) { xlsProcess[i].Kill(); } Process[] wordProcess = Process.GetProcessesByName("WINWORD"); for (int i = 0; i < wordProcess.Length; i++) { wordProcess[i].Kill(); } bWork.ReportProgress(20, "清理内存"); WORD.Application wordApp = null; EXCEL.Application excelApp = null; object missing = System.Reflection.Missing.Value; if (acRecs.Find(cc => cc.type == "word") != null) { wordApp = new WORD.Application(); } if (acRecs.Find(cc => cc.type == "excel") != null) { excelApp = new EXCEL.Application(); } int iCount = 0; #endregion #region 初始化锦囊 Dictionary<bool, Action<PrintDocument>> druplexStrategy = DAL.FILEPRINT.ActionModual.InitDruplexStrategy(); Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>> printStrategy = DAL.FILEPRINT.ActionModual.InitMappingPrintStrategy(druplexStrategy, pd, wordApp, excelApp); Dictionary<string, Action<REP.AdvanceSetting>> coolStrategy = DAL.FILEPRINT.ActionModual.InitCoolStrategy(); #endregion foreach (var rowRec in rowRecs) { #region 销毁word组件 if (iCount % int.Parse(advRec.loopNm) == 0 && iCount != 0) { bWork.ReportProgress(20, "销毁COM组件,清理内存.."); if (wordApp != null) { wordApp.Quit(ref missing, ref missing, ref missing); //Marshal.ReleaseComObject(wordApp); //Marshal.FinalReleaseComObject(wordApp); wordApp = null; } if (excelApp != null) { excelApp.Quit(); //Marshal.ReleaseComObject(excelApp); //Marshal.FinalReleaseComObject(excelApp); excelApp = null; } System.GC.Collect(); wordApp = new WORD.Application(); excelApp = new EXCEL.Application(); } #endregion foreach (var acRec in acRecs) { for (int i = 0; i < acRec.Amount; i++) { try { //打印 printStrategy[acRec.type].Invoke(folderPath, acRec, genRec, rowRec); } catch (Exception ex) { throw new Exception(ex.Message + "\n打印动作名称:" + acRec.ActionName + "\n被打印的数据:" + rowRec.value.ToString()); } //冷却 coolStrategy[acRec.type].Invoke(advRec); } } } } public static void PrintByGroupRecs(PrintDocument pd, List<REP.IAction> acRecs, REP.GeneralSetting genRec, REP.AdvanceSetting advRec, List<REP.UnitRec> unitRecs, string folderPath, BackgroundWorker bWork) { #region 清理环境 Process[] xlsProcess = Process.GetProcessesByName("EXCEL"); for (int i = 0; i < xlsProcess.Length; i++) { xlsProcess[i].Kill(); } Process[] wordProcess = Process.GetProcessesByName("WINWORD"); for (int i = 0; i < wordProcess.Length; i++) { wordProcess[i].Kill(); } bWork.ReportProgress(20, "清理内存"); WORD.Application wordApp = null; EXCEL.Application excelApp = null; object missing = System.Reflection.Missing.Value; if (acRecs.Find(cc => cc.type == "word") != null) { wordApp = new WORD.Application(); } if (acRecs.Find(cc => cc.type == "excel") != null) { excelApp = new EXCEL.Application(); } int iCount = 0; #endregion #region 初始化锦囊 Dictionary<bool, Action<PrintDocument>> druplexStrategy = DAL.FILEPRINT.ActionModual.InitDruplexStrategy(); Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting, REP.RowRecord>> printStrategy = DAL.FILEPRINT.ActionModual.InitMappingPrintStrategy(druplexStrategy, pd, wordApp,excelApp); Dictionary<string, Action<REP.AdvanceSetting>> coolStrategy = DAL.FILEPRINT.ActionModual.InitCoolStrategy(); #endregion foreach (var unitRec in unitRecs) { if (System.Windows.Forms.MessageBox.Show("是否打印" + unitRec.Address + "所属数据", "请确定", System.Windows.Forms.MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK) { foreach (var rowRec in unitRec.records) { #region 销毁word组件 if (iCount % int.Parse(advRec.loopNm) == 0 && iCount != 0) { bWork.ReportProgress(20, "销毁COM组件,清理内存.."); if (wordApp != null) { wordApp.Quit(ref missing, ref missing, ref missing); //Marshal.ReleaseComObject(wordApp); //Marshal.FinalReleaseComObject(wordApp); wordApp = null; } if (excelApp != null) { excelApp.Quit(); //Marshal.ReleaseComObject(excelApp); //Marshal.FinalReleaseComObject(excelApp); excelApp = null; } System.GC.Collect(); wordApp = new WORD.Application(); excelApp = new EXCEL.Application(); } #endregion foreach (var acRec in acRecs) { for (int i = 0; i < acRec.Amount; i++) { try { //打印 printStrategy[acRec.type].Invoke(folderPath, acRec, genRec, rowRec); } catch (Exception ex) { throw new Exception(ex.Message + "\n打印动作名称:" + acRec.ActionName + "\n被打印的数据:" + rowRec.value.ToString()); } //冷却 coolStrategy[acRec.type].Invoke(advRec); } } } } } } public static void PrintDirect(PrintDocument pd, List<REP.IAction> acRecs, REP.GeneralSetting genRec, REP.AdvanceSetting advRec, string folderPath, BackgroundWorker bWork) { #region 清理环境 Process[] xlsProcess = Process.GetProcessesByName("EXCEL"); for (int i = 0; i < xlsProcess.Length; i++) { xlsProcess[i].Kill(); } Process[] wordProcess = Process.GetProcessesByName("WINWORD"); for (int i = 0; i < wordProcess.Length; i++) { wordProcess[i].Kill(); } bWork.ReportProgress(20, "清理内存"); WORD.Application wordApp = null; EXCEL.Application excelApp = null; object missing = System.Reflection.Missing.Value; if (acRecs.Find(cc => cc.type == "word") != null) { wordApp = new WORD.Application(); } if (acRecs.Find(cc => cc.type == "excel") != null) { excelApp = new EXCEL.Application(); } int iCount = 0; #endregion #region 初始化锦娘 Dictionary<bool, Action<PrintDocument>> druplexStrategy = DAL.FILEPRINT.ActionModual.InitDruplexStrategy(); Dictionary<string, Action<string, REP.IAction, REP.GeneralSetting>> printStrategy = DAL.FILEPRINT.ActionModual.InitDirectPrintStrategy(druplexStrategy, pd, wordApp, excelApp); Dictionary<string, Action<REP.AdvanceSetting>> coolStrategy = DAL.FILEPRINT.ActionModual.InitCoolStrategy(); #endregion foreach (var acRec in acRecs) { #region 销毁word组件 if (iCount % int.Parse(advRec.loopNm) == 0 && iCount != 0) { bWork.ReportProgress(20, "销毁COM组件,清理内存.."); if (wordApp != null) { wordApp.Quit(ref missing, ref missing, ref missing); //Marshal.ReleaseComObject(wordApp); //Marshal.FinalReleaseComObject(wordApp); wordApp = null; } if (excelApp != null) { excelApp.Quit(); Marshal.ReleaseComObject(excelApp); Marshal.FinalReleaseComObject(excelApp); excelApp = null; } System.GC.Collect(); wordApp = new WORD.Application(); excelApp = new EXCEL.Application(); } #endregion for (int i = 0; i < acRec.Amount; i++) { //打印 try { printStrategy[acRec.type].Invoke(folderPath, acRec, genRec); } catch (Exception ex) { throw new Exception(ex.Message + "\n打印动作名称:" + acRec.ActionName + "\n被打印的数据:" + folderPath); } //冷却 coolStrategy[acRec.type].Invoke(advRec); } } } } }
3.双面打印设置
using System.Runtime.InteropServices; using System; namespace MyDuplexSettings { class DuplexSettings { #region Win32 API Declaration [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern Int32 GetLastError(); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg, IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode); [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel, IntPtr pPrinter, Int32 dwBuf, ref Int32 dwNeeded); [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, ref PRINTER_DEFAULTS pDefault); [DllImport("winspool.Drv", EntryPoint = "SetPrinterA", ExactSpelling = true, SetLastError = true)] public static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command); [StructLayout(LayoutKind.Sequential)] public struct PRINTER_DEFAULTS { public IntPtr pDatatype; public IntPtr pDevMode; public int DesiredAccess; } [StructLayout(LayoutKind.Sequential)] public struct PRINTER_INFO_9 { public IntPtr pDevMode; // Pointer to SECURITY_DESCRIPTOR public int pSecurityDescriptor; } public const short CCDEVICENAME = 32; public const short CCFORMNAME = 32; [StructLayout(LayoutKind.Sequential)] public struct DEVMODE { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)] public string dmDeviceName; public short dmSpecVersion; public short dmDriverVersion; public short dmSize; public short dmDriverExtra; public int dmFields; public short dmOrientation; public short dmPaperSize; public short dmPaperLength; public short dmPaperWidth; public short dmScale; public short dmCopies; public short dmDefaultSource; public short dmPrintQuality; public short dmColor; public short dmDuplex; public short dmYResolution; public short dmTTOption; public short dmCollate; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)] public string dmFormName; public short dmUnusedPadding; public short dmBitsPerPel; public int dmPelsWidth; public int dmPelsHeight; public int dmDisplayFlags; public int dmDisplayFrequency; } public const Int64 DM_DUPLEX = 0x1000L; public const Int64 DM_ORIENTATION = 0x1L; public const Int64 DM_SCALE = 0x10L; public const Int64 DMORIENT_PORTRAIT = 0x1L; public const Int64 DMORIENT_LANDSCAPE = 0x2L; public const Int32 DM_MODIFY = 8; public const Int32 DM_COPY = 2; public const Int32 DM_IN_BUFFER = 8; public const Int32 DM_OUT_BUFFER = 2; public const Int32 PRINTER_ACCESS_ADMINISTER = 0x4; public const Int32 PRINTER_ACCESS_USE = 0x8; public const Int32 STANDARD_RIGHTS_REQUIRED = 0xf0000; public const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE); //added this public const int CCHDEVICENAME = 32; //added this public const int CCHFORMNAME = 32; #endregion #region Public Methods /// <summary> /// Method Name : GetPrinterDuplex /// Programmatically get the Duplex flag for the specified printer /// driver's default properties. /// </summary> /// <param name="sPrinterName"> The name of the printer to be used. </param> /// <param name="errorMessage"> this will contain error messsage if any. </param> /// <returns> /// nDuplexSetting - One of the following standard settings: /// 0 = Error /// 1 = None (Simplex) /// 2 = Duplex on long edge (book) /// 3 = Duplex on short edge (legal) /// </returns> /// <remarks> /// </remarks> public short GetPrinterDuplex(string sPrinterName, out string errorMessage) { errorMessage = string.Empty; short functionReturnValue = 0; IntPtr hPrinter = default(IntPtr); PRINTER_DEFAULTS pd = default(PRINTER_DEFAULTS); DEVMODE dm = new DEVMODE(); int nRet = 0; pd.DesiredAccess = PRINTER_ACCESS_USE; nRet = OpenPrinter(sPrinterName, out hPrinter, ref pd); if ((nRet == 0) | (hPrinter.ToInt32() == 0)) { if (GetLastError() == 5) { errorMessage = "Access denied -- See the article for more info."; } else { errorMessage = "Cannot open the printer specified " + "(make sure the printer name is correct)."; } return functionReturnValue; } nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, IntPtr.Zero, IntPtr.Zero, 0); if ((nRet < 0)) { errorMessage = "Cannot get the size of the DEVMODE structure."; goto cleanup; } IntPtr iparg = Marshal.AllocCoTaskMem(nRet + 100); nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, iparg, IntPtr.Zero, DM_OUT_BUFFER); if ((nRet < 0)) { errorMessage = "Cannot get the DEVMODE structure."; goto cleanup; } dm = (DEVMODE)Marshal.PtrToStructure(iparg, dm.GetType()); if (!Convert.ToBoolean(dm.dmFields & DM_DUPLEX)) { errorMessage = "You cannot modify the duplex flag for this printer " + "because it does not support duplex or the driver " + "does not support setting it from the Windows API."; goto cleanup; } functionReturnValue = dm.dmDuplex; cleanup: if ((hPrinter.ToInt32() != 0)) ClosePrinter(hPrinter); return functionReturnValue; } /// <summary> /// Method Name : SetPrinterDuplex /// Programmatically set the Duplex flag for the specified printer driver's default properties. /// </summary> /// <param name="sPrinterName"> sPrinterName - The name of the printer to be used. </param> /// <param name="nDuplexSetting"> /// nDuplexSetting - One of the following standard settings: /// 1 = None /// 2 = Duplex on long edge (book) /// 3 = Duplex on short edge (legal) /// </param> /// <param name="errorMessage"> this will contain error messsage if any. </param> /// <returns> /// Returns: True on success, False on error. /// </returns> /// <remarks> /// /// </remarks> public bool SetPrinterDuplex(string sPrinterName, int nDuplexSetting, out string errorMessage) { errorMessage = string.Empty; bool functionReturnValue = false; IntPtr hPrinter = default(IntPtr); PRINTER_DEFAULTS pd = default(PRINTER_DEFAULTS); PRINTER_INFO_9 pinfo = new PRINTER_INFO_9(); DEVMODE dm = new DEVMODE(); IntPtr ptrPrinterInfo = default(IntPtr); int nBytesNeeded = 0; int nRet = 0; Int32 nJunk = default(Int32); if ((nDuplexSetting < 1) | (nDuplexSetting > 3)) { errorMessage = "Error: dwDuplexSetting is incorrect."; return functionReturnValue; } pd.DesiredAccess = PRINTER_ACCESS_USE; nRet = OpenPrinter(sPrinterName, out hPrinter, ref pd); if ((nRet == 0) | (hPrinter.ToInt32() == 0)) { if (GetLastError() == 5) { errorMessage = "Access denied -- See the article for more info."; } else { errorMessage = "Cannot open the printer specified " + "(make sure the printer name is correct)."; } return functionReturnValue; } nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, IntPtr.Zero, IntPtr.Zero, 0); if ((nRet < 0)) { errorMessage = "Cannot get the size of the DEVMODE structure."; goto cleanup; } IntPtr iparg = Marshal.AllocCoTaskMem(nRet + 100); nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, iparg, IntPtr.Zero, DM_OUT_BUFFER); if ((nRet < 0)) { errorMessage = "Cannot get the DEVMODE structure."; goto cleanup; } dm = (DEVMODE)Marshal.PtrToStructure(iparg, dm.GetType()); if (!Convert.ToBoolean(dm.dmFields & DM_DUPLEX)) { errorMessage = "You cannot modify the duplex flag for this printer " + "because it does not support duplex or the driver " + "does not support setting it from the Windows API."; goto cleanup; } dm.dmDuplex = (short)nDuplexSetting; Marshal.StructureToPtr(dm, iparg, true); nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, pinfo.pDevMode, pinfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); if ((nRet < 0)) { errorMessage = "Unable to set duplex setting to this printer."; goto cleanup; } GetPrinter(hPrinter, 9, IntPtr.Zero, 0, ref nBytesNeeded); if ((nBytesNeeded == 0)) { errorMessage = "GetPrinter failed."; goto cleanup; } ptrPrinterInfo = Marshal.AllocCoTaskMem(nBytesNeeded + 100); nRet = GetPrinter(hPrinter, 9, ptrPrinterInfo, nBytesNeeded, ref nJunk) ? 1 : 0; if ((nRet == 0)) { errorMessage = "Unable to get shared printer settings."; goto cleanup; } pinfo = (PRINTER_INFO_9)Marshal.PtrToStructure(ptrPrinterInfo, pinfo.GetType()); pinfo.pDevMode = iparg; pinfo.pSecurityDescriptor = 0; Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true); nRet = SetPrinter(hPrinter, 9, ptrPrinterInfo, 0) ? 1 : 0; if ((nRet == 0)) { errorMessage = "Unable to set shared printer settings."; } functionReturnValue = Convert.ToBoolean(nRet); cleanup: if ((hPrinter.ToInt32() != 0)) ClosePrinter(hPrinter); return functionReturnValue; } #endregion } }