在前段时间做了一下打印,因为需要支持的格式比较多,所以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. Axure学习(一)

    了解Axure目前的一些评价信息以及可以学习Axure的网址.

  2. java 多态的深入理解

    简单来说 : 多态 能够很好的解决代码耦合性的问题 考虑这样一个场景 有个人 买了辆捷达汽车 .这个系统应该如何设计呢? public class JettaCar { public void run ...

  3. C#动态显示时间

    private void timer1_Tick(object sender, EventArgs e) { DateTime dt = DateTime.Now; label1.Text = dt. ...

  4. GOIP connects with Elastix through “config by line”

    GOIP connects with Elastix through “config by line” By grace Liu on May 17, 2013 in Elastix, Gateway ...

  5. web.xml 详细介绍(zz)

    web.xml 详细介绍 博客分类: CoreJava WebXMLServletJSPTomcat  http://mianhuaman.iteye.com/blog/1105522 1.启动一个W ...

  6. 13个开源GIS软件 你了解几个?

    地理信息系统(Geographic Information System,GIS)软件依赖于覆盖整个地球的数据集.为处理大量的 GIS 数据及其格式,编程人员创建了若干开源库和 GIS 套件. GIS ...

  7. OpenCV-图像通道转换问题

    OpenCV-MAT对象中使用plt.imshow(img[:,:,::-1])如何实现将第二轴反向? 系统平台:win10 x64 一.明确几个概念: 1.OpenCV内部每个通道并没有固定对应某种 ...

  8. 2018.10.29 NOIP训练 数据结构(带修改莫队)

    传送门 带修莫队板题. 直接按照经典写法做就行了. 代码

  9. 获取POM.XML依赖的JAR包

    pom.xml 文件的依赖在本地仓库中,有些情况我需要根据pom.xml 抓取所有依赖的JAR包. 这个可以通过 ant 完成这个包的抓取. <target name="maven-j ...

  10. greenplum 开启和关闭服务

    1.关闭服务$pg_ctl stop -m fast -D $MASTER_DATA_DIRECTORY (/usr/local/greenplum-db/bin) 2.开启服务 $pg_ctl st ...