求助,关于打印?

hotnoodle 2003-07-20 10:01:37
我在打印时遇到这样一个问题,单纯的用System.Drawing.Printing.PrintDocument控件的Print功能时可以正常的打印出所有的页面,但将打印文档绑定到PrintPreviewDialog控件中,使用PrintPreviewDialog打印时就只能打印出第一页,后面的页面在PrintPreviewDialog控件中可以显示出来,就是打印不出来。请高手指点?
...全文
30 5 打赏 收藏 举报
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
cellblue 2003-07-20
  • 打赏
  • 举报
回复

// uncomment these lines to draw borders around the rectangles
/*
drawRect(ev.Graphics, _defaultPen, leftMargin, topMargin, pageWidth, headerHeight);
drawRect(ev.Graphics, _defaultPen, leftMargin, ReportheaderR.Bottom, pageWidth, pageHeight - ReportheaderR.Height - footerHeight);
drawRect(ev.Graphics, _defaultPen, leftMargin, bodyR.Bottom, pageWidth, ReportfooterR.Height);

centerText(ev.Graphics, "Header section", _headerFont, _defaultBrush, ReportheaderR);
centerText(ev.Graphics, "Body section", _headerFont, _defaultBrush, bodyR);
centerText(ev.Graphics, "Footer section", _headerFont, _defaultBrush, ReportfooterR);
return;
*/

// results of using the Split function on the text
String[] data;
// a line of text from our file
string text = "";

// print the header once per page
centerText(ev.Graphics, headerText, _headerFont, _defaultBrush, ReportheaderR);

// how many lines can we fit on a page?
float bodyFontHeight = footerHeight;
int linesPerPage = Convert.ToInt32(bodyR.Height / bodyFontHeight) - 1;

// the header = 2 lines
int currentLine = 2;
// currentY is what we'll use for the Top (Y) coordinate that
// DrawString needs.
float currentY = 0;

// Print each line of the file. This could be easily modified to
// deal with data from a DataTable
while(currentLine + 1 < linesPerPage && ((text=_Data.ReadLine()) != null))
{

data = text.Split(',');

// retrieve the current top position
currentY = getCurrentY(currentLine++, bodyR.Top, bodyFontHeight);
// DrawString will take a Rectangle argument, but NOT a RectangleF arg,
// so we need to provide the X and Y arguments.
ev.Graphics.DrawString(data[0], _bodyFont, _defaultBrush, bodyR.Left, currentY);
currentY = getCurrentY(currentLine++, bodyR.Top, bodyFontHeight);
ev.Graphics.DrawString(data[1], _bodyFont, _defaultBrush, bodyR.Left + 25, currentY);
currentY = getCurrentY(currentLine++, bodyR.Top, bodyFontHeight);
ev.Graphics.DrawString("Phone: " + data[2], _bodyFont, _defaultBrush, bodyR.Left + 25, currentY);
currentY = getCurrentY(currentLine++, bodyR.Top, bodyFontHeight);
ev.Graphics.DrawString("Fax: " + data[3], _bodyFont,_defaultBrush, bodyR.Left + 25, currentY);
//currentY = getCurrentY(currentLine++, topMargin, bodyFontHeight);
//ev.Graphics.DrawLine(_defaultPen, leftMargin, currentY, pageWidth, currentY);
currentLine++;
}

// page number
centerText(ev.Graphics, "Page " + _currentPage.ToString(), _bodyFont, _defaultBrush, ReportfooterR);

// Do we have more pages to print?
if (text != null)
{
ev.HasMorePages = true;
}
else
{
ev.HasMorePages = false;
}
}

private float getCurrentY(int currentLine, float topMargin, float fontHeight)
{
return topMargin + (currentLine * fontHeight);
}

// my wrapper for DrawRectangle
private void drawRect(Graphics g, Pen p, float left, float top, float width, float height)
{
g.DrawRectangle(_defaultPen, left, top, width, height);
}

// the StringFormat class has a lot of cool features
private void centerText(Graphics g, string t, Font f, Brush b, RectangleF rect)
{
StringFormat sf = new StringFormat();
// center horizontally
sf.Alignment = StringAlignment.Center;
// center vertically
sf.LineAlignment = StringAlignment.Center;
g.DrawString(t, f, b, rect, sf);
}

// used for debugging
private void dumpRectF(RectangleF rect)
{
System.Diagnostics.Debug.WriteLine(rect.ToString());
}

private void _PDoc_BeginPrint(object sender, PrintEventArgs pv)
{
// make sure we reset this before printing
_currentPage = 0;

// the file should be in the same folder as the EXE
_Data = new StreamReader("contacts.csv");
_headerFont = new Font("Arial", 24, FontStyle.Underline, GraphicsUnit.World);
_bodyFont = new Font("Arial", 12, GraphicsUnit.World);
}

private void _PDoc_EndPrint(object sender, PrintEventArgs pv)
{
_Data.Close();
_headerFont.Dispose();
_bodyFont.Dispose();
}

private void _PDoc_QueryPageSettings(object sender, QueryPageSettingsEventArgs ev)
{

}

private void PrintForm_Load(object sender, System.EventArgs e)
{
_PDoc = new PrintDocument();
// this is what will show up in the print manager
_PDoc.DocumentName = "printTest -- Northwind Contact List";
// make sure at least one printer is installed
if (_PDoc.PrinterSettings.PrinterName == "<no default printer>")
{
StatusLabel.Text = "At least one (1) printer must be installed to continue.";
PrintButton.Enabled = false;
PreviewButton.Enabled = false;
}
else
{
StatusLabel.Text = "You have " + PrinterSettings.InstalledPrinters.Count + " printer(s) installed.";
// bind the events
_PDoc.PrintPage += new PrintPageEventHandler(_PDoc_PrintPage);
_PDoc.BeginPrint += new PrintEventHandler(_PDoc_BeginPrint);
_PDoc.EndPrint += new PrintEventHandler(_PDoc_EndPrint);
_PDoc.QueryPageSettings += new QueryPageSettingsEventHandler(_PDoc_QueryPageSettings);
}
}

private void PrintButton_Click(object sender, System.EventArgs e)
{
PrintDialog pd = new PrintDialog();
pd.Document = _PDoc;
DialogResult Rc = pd.ShowDialog();

if (Rc == DialogResult.OK)
{
_PDoc.Print();
}
}
}
}
cellblue 2003-07-20
  • 打赏
  • 举报
回复
以下内容存放在PrintForm.cs中


using System;
using System.IO;
using System.Drawing;
using System.Drawing.Printing;
using System.ComponentModel;
using System.Windows.Forms;

namespace printTest
{
public class PrintForm : System.Windows.Forms.Form
{

// private variables
private PrintDocument _PDoc;
private StreamReader _Data;
private int _currentPage = 0;
// these will be created in BeginPrint and
// destroyed in EndPrint.
private Font _headerFont;
private Font _bodyFont;
private Brush _defaultBrush = Brushes.Black;
private Pen _defaultPen = new Pen(Brushes.Black, .25f);

private System.Windows.Forms.Button PreviewButton;
private System.Windows.Forms.Button PrintButton;
private System.Windows.Forms.Label StatusLabel;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public PrintForm() {
InitializeComponent();
}

protected override void Dispose( bool disposing ) {
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.PreviewButton = new System.Windows.Forms.Button();
this.PrintButton = new System.Windows.Forms.Button();
this.StatusLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// PreviewButton
//
this.PreviewButton.Location = new System.Drawing.Point(108, 40);
this.PreviewButton.Name = "PreviewButton";
this.PreviewButton.TabIndex = 1;
this.PreviewButton.Text = "Preview";
this.PreviewButton.Click += new System.EventHandler(this.PreviewButton_Click);
//
// PrintButton
//
this.PrintButton.Location = new System.Drawing.Point(188, 40);
this.PrintButton.Name = "PrintButton";
this.PrintButton.TabIndex = 2;
this.PrintButton.Text = "Print";
this.PrintButton.Click += new System.EventHandler(this.PrintButton_Click);
//
// StatusLabel
//
this.StatusLabel.Location = new System.Drawing.Point(9, 8);
this.StatusLabel.Name = "StatusLabel";
this.StatusLabel.Size = new System.Drawing.Size(352, 23);
this.StatusLabel.TabIndex = 3;
this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// PrintForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(370, 71);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.StatusLabel,
this.PrintButton,
this.PreviewButton});
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "PrintForm";
this.Text = "Print Demo";
this.Load += new System.EventHandler(this.PrintForm_Load);
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new PrintForm());
}

private void PreviewButton_Click(object sender, System.EventArgs e)
{
PrintPreviewDialog previewDialog = new PrintPreviewDialog();

// display a pagesetup dialog
PageSetupDialog pageSetup = new PageSetupDialog();
pageSetup.Document = _PDoc;
DialogResult Rc = pageSetup.ShowDialog();
if (Rc == DialogResult.Cancel)
{
return;
}

// display the preview dialog
previewDialog.Document = _PDoc;
previewDialog.PrintPreviewControl.Zoom = 1.0;
previewDialog.WindowState = FormWindowState.Maximized;
previewDialog.ShowInTaskbar = true;
previewDialog.ShowDialog();
}

private void _PDoc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs ev)
{

_currentPage++;

String headerText = "Northwinds Customer Contacts";

marginInfo mi;

float leftMargin = 0f;
float rightMargin = 0f;
float topMargin = 0f;
float bottomMargin = 0f;
float pageHeight = 0f;
float pageWidth = 0f;

// retrieve the hard printer margins
IntPtr hDc = ev.Graphics.GetHdc();
try
{
mi = new marginInfo(hDc.ToInt32());
}
finally
{
ev.Graphics.ReleaseHdc(hDc);
}

ev.Graphics.PageUnit = GraphicsUnit.Inch;
ev.Graphics.PageScale = .01f;
ev.Graphics.TranslateTransform(-mi.Left, -mi.Top);

// retrieve the margins
leftMargin = ev.MarginBounds.Left - mi.Left;
rightMargin = ev.MarginBounds.Right;
topMargin = ev.MarginBounds.Top - mi.Top;
bottomMargin = ev.MarginBounds.Bottom;
pageHeight = bottomMargin - topMargin;
pageWidth = rightMargin - leftMargin;

// used to define the sections of the document
float headerHeight = _headerFont.GetHeight(ev.Graphics);
float footerHeight = _bodyFont.GetHeight(ev.Graphics);

// report header
RectangleF ReportheaderR = new RectangleF(leftMargin, topMargin, pageWidth, headerHeight);
// report body
RectangleF bodyR = new RectangleF(leftMargin, ReportheaderR.Bottom, pageWidth, pageHeight - ReportheaderR.Height - footerHeight);
// report footer
RectangleF ReportfooterR = new RectangleF(leftMargin, bodyR.Bottom, pageWidth, footerHeight * 2);

cellblue 2003-07-20
  • 打赏
  • 举报
回复
给你看一段代码

以下内容存放在printStuff.cs中


using System;
using System.IO;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Printing;

namespace printTest {

// this is how you would create your own PrintDocument class that
// inherits from PrintDocument. You need to provide implementation
// code for the events you plan to use (at least OnPrintPage).
public class CustomPrintDocument : PrintDocument {

private StreamReader dataToPrint;

public CustomPrintDocument(StreamReader data) : base() {
dataToPrint = data;
}

protected override void OnBeginPrint(PrintEventArgs ev) {
base.OnBeginPrint(ev) ;
}

protected override void OnEndPrint(PrintEventArgs ev) {
base.OnEndPrint(ev);
}

protected override void OnQueryPageSettings(QueryPageSettingsEventArgs ev) {
base.OnQueryPageSettings(ev);
}

protected override void OnPrintPage(PrintPageEventArgs ev) {
base.OnPrintPage(ev);

ev.Graphics.DrawString("this is a test", new Font("Arial", 24), Brushes.Black, 100, 100);
ev.HasMorePages = false;
}
}

public class marginInfo {
[DllImport("gdi32.dll")]
private static extern Int16 GetDeviceCaps([In] [MarshalAs (UnmanagedType.U4)] int hDc, [In] [MarshalAs (UnmanagedType.U2)] Int16 funct);

private float _leftMargin = 0;
private float _topMargin = 0;
private float _rightMargin = 0;
private float _bottomMargin = 0;

const short HORZSIZE = 4; /* Horizontal size in millimeters */
const short VERTSIZE = 6; /* Vertical size in millimeters */
const short HORZRES = 8; /* Horizontal width in pixels */
const short VERTRES = 10; /* Vertical height in pixels*/
const short PHYSICALOFFSETX = 112; /* Physical Printable Area x margin */
const short PHYSICALOFFSETY = 113; /* Physical Printable Area y margin */

// Modified from code originally written by Ron Allen (Ron@us-src.com).
public marginInfo(int deviceHandle) {
// Non printable margin in pixels
float offsetX = Convert.ToSingle(GetDeviceCaps(deviceHandle, PHYSICALOFFSETX));
float offsetY = Convert.ToSingle(GetDeviceCaps(deviceHandle, PHYSICALOFFSETY));
// printable page size in pixels
float resolutionX = Convert.ToSingle(GetDeviceCaps(deviceHandle, HORZRES));
float resolutionY = Convert.ToSingle(GetDeviceCaps(deviceHandle, VERTRES));
// printable page size in current unit (in this case, converted to inches)
float horizontalSize = Convert.ToSingle(GetDeviceCaps(deviceHandle, HORZSIZE))/25.4f;
float verticalSize = Convert.ToSingle(GetDeviceCaps(deviceHandle, VERTSIZE))/25.4f;

float pixelsPerInchX = resolutionX/horizontalSize;
float pixelsPerInchY = resolutionY/verticalSize;

_leftMargin = (offsetX/pixelsPerInchX)* 100.0f;
_topMargin = (offsetY/pixelsPerInchX) * 100.0f;
_bottomMargin = _topMargin + (verticalSize * 100.0f);
_rightMargin = _leftMargin + (horizontalSize * 100.0f);
}

public float Left {
get {
return _leftMargin;
}
}

public float Right {
get {
return _rightMargin;
}
}

public float Top {
get {
return _topMargin;
}
}

public float Bottom {
get {
return _bottomMargin;
}
}

public override string ToString() {
return "left=" + _leftMargin.ToString() + ", top=" + _topMargin.ToString() + ", right=" + _rightMargin.ToString() + ", bottom=" + _bottomMargin.ToString();
}

}
}
hotnoodle 2003-07-20
  • 打赏
  • 举报
回复
有,用System.Drawing.Printing.PrintDocument控件的Print功能时可以正常的打印出所有的页面。
visualcpu 2003-07-20
  • 打赏
  • 举报
回复
你有没有允许能打多页!

比如:e.hasmorepages=true可以分页!
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2003-07-20 10:01
社区公告

让您成为最强悍的C#开发者