C# – 如何打印宽高比/整页

我在点击按钮时打印CHART控件:

chart1.SaveImage(ms, ChartImageFormat.Bmp); Bitmap bm = new Bitmap(ms); PrintDocument doc = new PrintDocument(); doc.PrintPage += (s, ev) => { ev.Graphics.DrawImage(bm, Point.Empty); // adjust this to put the image elsewhere ev.HasMorePages = false; }; doc.DefaultPageSettings.Landscape = true; doc.Print(); 

如何强制它打印控件以使其适合页面大小(保留纵横比)?

至少有两种不同的方法, 包括缩放要打印的图像以适合所选打印机的页面大小

1)使用.NET工具(我自己没有测试过,从这篇文章中取消):

  private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { Image i = pictureBox1.Image; float newWidth = i.Width * 100 / i.HorizontalResolution; float newHeight = i.Height * 100 / i.VerticalResolution; float widthFactor = newWidth / e.MarginBounds.Width; float heightFactor = newHeight / e.MarginBounds.Height; if(widthFactor>1 | heightFactor > 1) { if(widthFactor > heightFactor) { newWidth = newWidth / widthFactor; newHeight = newHeight / widthFactor; } else { newWidth = newWidth / heightFactor; newHeight = newHeight / heightFactor; } } e.Graphics.DrawImage(i, 0, 0, (int)newWidth, (int)newHeight); } } 

2) P /调用来自GDI和平面GDI的Windows API调用(这更复杂但更快,你可以传递位图文件的普通字节数组(读取文件为byte []),向我发送电子邮件如果需要这个代码):

  private static extern bool ClosePrinter(IntPtr hPrinter); private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); private static extern int SetJob(IntPtr hPrinter, int JobId, int Level, ref byte pJob, int Command_Renamed); private static extern int GdiplusStartup(out IntPtr token, ref StartupInput input, out StartupOutput output); private static extern int GdiplusShutdown(IntPtr token); internal static extern int GdipLoadImageFromStream([In, MarshalAs(UnmanagedType.Interface)]IStream stream, out IntPtr image); internal static extern int GdipDisposeImage(IntPtr image); static internal extern int GdipCreateFromHDC2(IntPtr hDC, IntPtr hDevice, out IntPtr graphics); static internal extern int GdipDeleteGraphics(IntPtr graphics); static internal extern int GdipReleaseDC(IntPtr graphics, IntPtr hdc); internal static extern int GdipGetImageDimension(IntPtr image, out float width, out float height); internal static extern int GdipGetDpiX(IntPtr graphics, out float dpi); internal static extern int GdipGetDpiY(IntPtr graphics, out float dpi); static internal extern int GdipDrawImageRectI(IntPtr graphics, IntPtr image, int x, int y, int width, int height); private static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPStr)] string lpszDriver, [MarshalAs(UnmanagedType.LPStr)] string lpszDevice, [MarshalAs(UnmanagedType.LPStr)] string lpszOutput, IntPtr lpInitData); private static extern bool DeleteDC(IntPtr hdc); private static extern int StartDoc(IntPtr hdc, DOCINFO lpdi); private static extern int EndDoc(IntPtr hdc); private static extern int StartPage(IntPtr hdc); private static extern int EndPage(IntPtr hdc); private static extern int GetDeviceCaps(IntPtr hdc, int nIndex); 

以下是我为实现这一目标所做的工作。 令人讨厌的是图表控件只会将其内容绘制为与屏幕大小相同的大小。 我发现解决这个问题的唯一方法是手动调整它。 然后,因为它可能不喜欢在表单上resize时,这也涉及暂时将其从表单中删除。

所以,尽管如此,我最终还是得到了这样的结论:

 Chart ChartBox { get; private set; } ... var oldParent = ChartBox.Parent; var oldSize = ChartBox.Size; ChartBox.Parent = null; ChartBox.Size = new Size(width, height); ChartBox.Printing.Print(); ChartBox.Parent = oldParent; ChartBox.Size = oldSize; 

根据您的表单,您可能还需要保存和恢复图表控件的其他属性。