在前段时间做了一下打印,因为需要支持的格式比较多,所以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 = ; 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 = ; //打印时页面设置,缩放比例百分之几
workSheet.PageSetup.Zoom = false; //打印时页面设置,必须设置为false,页高,页宽才有效
workSheet.PageSetup.FitToPagesWide = ; //设置页面缩放的页宽为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.5cm
workSheet.PageSetup.LeftMargin = / 0.035; //左边距为2cm
workSheet.PageSetup.RightMargin = / 0.035; //右边距为2cm
workSheet.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 = ;
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 = ;
double imgHeight = ;
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) <= ? : (_pageSize.Width - imgWidth)) / ;
double top = Math.Abs((_pageSize.Height - imgHeight) <= ? : (_pageSize.Height - imgHeight)) / ; 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 ;
}
}
#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 = , dwWritten = ;
IntPtr hPrinter = new IntPtr();
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, , 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();
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, , 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群。

WPF实战案例-打印的更多相关文章

  1. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  2. WPF实战案例-MVVM模式下在Xaml中弹出窗体

    相信很多学习和开发wpf项目的同学都了解过mvvm模式,同样,在mvvm模式下会有一个不可忽视的问题,就是怎么在xaml中弹出窗体,而不破坏MVVM本身的结构. 关于弹出窗体的方式还是很多的,本文先讲 ...

  3. WPF实战案例-数据代理

    在我们wpf开发中,很多人会有mvvm模式去做wpf的项目. 是否有人遇到这样一个场景:在一个界面上,有个tabcontrol上面有4个页签,每个页签里面都有一个datagrid,里面显示的列基本一样 ...

  4. WPF实战案例-在线程内同步集合数据到UI线程

    有这样一个场景,在vm中,我们为了ui的体验,会异步访问后端接口,获取数据集合,如果这个集合绑定到界面,并且在线程内,怎么处理? 有人讲:this.Dispatcher.Invoke,如果在vm内呢? ...

  5. WPF实战案例-MVVM模式下用附加属性在Xaml中弹出窗体

    嗯..最近回家去了,2个月没写过代码了,面试只能吹牛,基础都忘了,今天回顾一下,分享一篇通过附加属性去处理窗体弹出的情况. 或许老司机已经想到了,通过设置附加属性值,值变更的回调函数去处理窗体弹出,是 ...

  6. 3.awk数组详解及企业实战案例

    awk数组详解及企业实战案例 3.打印数组: [root@nfs-server test]# awk 'BEGIN{array[1]="zhurui";array[2]=" ...

  7. 企业Shell面试题及企业运维实战案例(三)

    1.企业Shell面试题1:批量生成随机字符文件名案例 使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下: ...

  8. (转)awk数组详解及企业实战案例

    awk数组详解及企业实战案例 原文:http://www.cnblogs.com/hackerer/p/5365967.html#_label03.打印数组:1. [root@nfs-server t ...

  9. shell脚本编程——生产实战案例

    生产实战案例     在日常的生产环境中,可能会遇到需要批量检查内网目前在线的主机IP地址有哪些,还可能需要检查这些在线的主机哪些端口是开放状态,因此依靠手工来检查是可以实现,但比较费时费力,所以需要 ...

随机推荐

  1. flask学习视频

    https://study.163.com/course/courseMain.htm?courseId=1004091002 主要 https://www.cnblogs.com/senlinyan ...

  2. C#调用开源图像识别类库tessnet2

    首先下载tessnet2_32.dll及相关语言包,将dll加入引用 private tessnet2.Tesseract ocr = new tessnet2.Tesseract();//声明一个O ...

  3. ContactDetail 和 ContactEditor 界面头像响应点击过程

    1,联系人详情界面 ContactDetailFragment中处理,ViewAdapter装载数据显示头像 private final class ViewAdapter extends BaseA ...

  4. c#里如何实现讲一个字符串数组例如 “112,221”转化成两个字符串数组“112” “221” 中间以逗号隔开

    比如是S [0]="123,223" S[1]="111,222" ....... 想转化为 SX[0]="123" SX[1]=" ...

  5. 33、iOS10 由于权限问题导致崩溃的大坑

    控制台报忠告: This app has crashed because it attempted to access privacy-sensitive data without a usage d ...

  6. 如何将本地代码通过git上传到码云

    ps:同部署到GitHub上一样 http://www.cnblogs.com/pcx105/p/7777932.html

  7. C语言常用数据类型说明

     1.取值范围: short一般占两个字节,取值范围:-32768 - 32767   int一般占两个或四个字节,取值范围:-2147483648 - 2147483647 unsigned int ...

  8. @RequestBody jackson解析复杂的传入值的一个坑;jackson解析迭代数组;jackson多重数组;jakson数组

    一.实际开发的一个问题. 传入一个json数组,数组中还嵌套数组,运用springboot+Jpa框架,@RequestBody注解传入数据 Controller @ApiOperation(valu ...

  9. Jersey RESTful WebService框架学习(三)使用@QueryParam

    介绍:@QueryParamuri路径请求参数写在方法的参数中,获得请求路径附带的参数.比如:@QueryParam("desc") String desc 前端控制 <!D ...

  10. Web墨卡托坐标与WGS84坐标互转

    原文地址:http://bbs.esrichina-bj.cn/ESRI/thread-78245-1-1.html 在WebGIS的开发中经常用到的地图投影为Web墨卡托和WGS84,故歌地图,bi ...