简体   繁体   English

使用PrintDocument打印多个页面

[英]Using PrintDocument to print multiple pages

I'm trying to print invoices. 我正在尝试打印发票。 Invoices should be able to be printed on multiple pages, but that's where the problem kicks in. I can perfectly print an invoice on a single page, but as soon as the invoice doesn't fit on a single page, the printjob just quits on the first page. 发票应该可以打印在多个页面上,但这就是问题所在。我可以在一个页面上完美地打印发票,但是一旦发票不适合单个页面,打印作业就会退出第一页。

Here's the code I'm using. 这是我正在使用的代码。 'artikelen' is a list of articles (List). 'artikelen'是一个文章列表(List)。 I have read several similar examples, and I'm fairly sure I'm missing something here. 我已经阅读了几个类似的例子,我很确定我在这里遗漏了一些东西。

(Edited: some unneccesary code deleted) (编辑:删除了一些不必要的代码)

public void PrintA4Factuur()
    {
        p = new PrintDocument();
        p.PrintPage +=
            new PrintPageEventHandler(printPage);
        printPreviewDialog.Document = p;
        printPreviewDialog.ShowDialog();
    }

void printPage(object sender1, PrintPageEventArgs e1)
    {
Graphics g = e1.Graphics;
int yPos = 320;
float pageHeight = e1.MarginBounds.Height;
int artikelPosition = 0;
while (yPos + 100 < pageHeight
            && artikelPosition < this.artikelen.Count)
        {
            // Do stuff with articles (printing details in different rectangles

            artikelPosition += 1;
            yPos += 20;
        }

        if (artikelPosition < this.artikelen.Count)
        {
            e1.HasMorePages = true;
            return;
        }
        else
        {
            e1.HasMorePages = false;
        }
}

Well, Lars pointed out the problem with resetting artikelPosition to zero at the start of each page, but there are a few other problems with this code. 好吧,Lars指出了在每个页面的开头将artikelPosition重置为零的问题,但是这个代码还存在一些其他问题。

You should always use e1.MarginBounds for coordinates, as margins can be changed by the user and p.DefaultPageSettings will not include that. 您应该始终使用e1.MarginBounds作为坐标,因为用户可以更改边距,而p.DefaultPageSettings将不包含该边距。

Use font metrics like GetHeight(yourDeviceGraphPort) , don't hard-code line heights. 使用像GetHeight(yourDeviceGraphPort)这样的字体指标,不要硬编码行高。

Always use float s for coordinates, do not convert between int s. 始终使用float s作为坐标,不要在int之间转换。

Fonts are non-managed resources, you must Dispose them when you are done with them. 字体都是非托管资源,你必须Dispose他们,当你与他们所做的。 It is inefficient to create and dispose fonts repeatedly in a loop; 在循环中重复创建和处理字体是低效的; construct it before calling PrintDocument.Print() and dispose it after all pages have printed. 在调用PrintDocument.Print()之前构造它,并在打印PrintDocument.Print()所有页面后对其进行处理。

There is also a Black SolidBrush already defined in System.Drawing . System.Drawing还定义了一个Black SolidBrush。

I found your code to do the opposite: if it prints more than one page, it continues to print into infinity. 我发现你的代码反其道而行之:如果它打印多个页面,它会继续打印到无穷大。

Try moving your index position variable outside of the PrintPage event, because setting it back to zero just sets it to the beginning again: 尝试将您的索引位置变量移动到PrintPage事件之外,因为将其设置回零只是将其再次设置为开头:

int artikelPosition = 0;

Reset it when you start the printing: 开始打印时重置它:

public void PrintA4Factuur()
{
  artikelPosition = 0

  p = new PrintDocument();
  p.PrintPage += printPage;
  printPreviewDialog.Document = p;
  printPreviewDialog.ShowDialog();
}

Then comment it out in your PrintPage routine: 然后在PrintPage例程中注释掉它:

void printPage(object sender1, PrintPageEventArgs e1)
{
  Graphics g = e1.Graphics;
  int yPos = 320;
  float pageHeight = e1.MarginBounds.Height;

  // int artikelPosition = 0;

  // continue with code
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM