2012-04-23 47 views
3

我必须打印我们公司生产的产品的运输标签。PrintPage PrintPageEventHandler正在打印太多副本

为了让自己感觉这些标签会变成什么样子,我使用Windows窗体来设计它们。这允许我定位我的文本,获取字体设置等,使用Label控件,添加自定义BarCode控件,并获得“花式”与Panel控件将项目分组为框。

每页都有两(2)个标签。

当我的代码打印标签文档时,我要求2,4或6份副本。偶尔也会使用打印预览。在这种情况下,我必须重置所创建标签的数量。

然而,当文件打印:

  • 如果请求的是2份,将码打印2张纸(4个标签)
  • 如果请求的是4份,代码打印8张纸(16个标记)
  • 如果请求的是6份,所述代码打印高达18页(36个标记)

有谁看到一个模式?我不。

这是我的打印命令:

public int Print(string docName, int rows, int columns, int copies) { 
    short shortCopies = (short)copies; 
    LabelsHorizontal = rows; 
    LabelsVertical = columns; 
    Size docSize = PrintPreview.Document.DefaultPageSettings.Bounds.Size; 
    float height = 0.8F * Screen.PrimaryScreen.WorkingArea.Size.Height; 
    float width = (height * docSize.Width)/docSize.Height; 
    Size winSize = new Size((int)width, (int)height); 
    PrintPreview.Height = winSize.Height; 
    PrintPreview.Width = winSize.Width; 
    if (!String.IsNullOrEmpty(docName)) { 
    PrintPreview.Document.DocumentName = docName; 
    } 
    PrintPreview.Document.PrinterSettings.Copies = shortCopies; 
    PrintPreview.SettingsFilename = Settings.PageSettingsLocation; 
    if (!PrintPreview.PrinterSelected) { 
    if (PrintPreview.ShowPrinterSelectDialog() != DialogResult.OK) { 
     return 0; 
    } 
    } 
    labelQtyPrinted = 0; 
    if (ShowPrintPreview) { 
    PrintPreview.ShowDialog(); 
    } else { 
    PrintPreview.PrintDocument(); 
    } 
    return labelQtyPrinted; 
} 
// Resets the Label Count between PrintPreview and Print 
private void PrintPreview_OnPrintClicked(object sender, EventArgs e) { 
    labelQtyPrinted = 0; 
} 

我不得不写一个自定义的打印预览类,它的PrintPreviewDialog作为基类,这样我可以用这个printButton_Click方法来覆盖它的打印按钮:

// Handles the Printing of the Document 
internal void printButton_Click(object sender, EventArgs e) { 
    if (OnPrintClicked != null) { 
    OnPrintClicked(sender, e); // this resets my labelQtyPrinted value shown above 
    } 
    Document.Print(); 
    printed = true; 
    Close(); 
} 

Print方法(第一个代码片断),PrintPreview.PrintDocument()只是代码调用printButton_Click事件。

PrintPageEventHandler如下图所示:

private void Document_Printed(object sender, PrintPageEventArgs e) { 
    if (PrintPreview.Document.PrinterSettings.Copies <= labelQtyPrinted) { 
    throw new Exception("Run Away Printer"); 
    } 
    float scale; 
    SizeF pageSize = new SizeF(
    PrintPreview.Document.DefaultPageSettings.PaperSize.Width, 
    PrintPreview.Document.DefaultPageSettings.PaperSize.Height 
); 
    Margins m = PrintPreview.Document.DefaultPageSettings.Margins; 
    float printableHeight = pageSize.Height - (m.Top + m.Bottom); 
    float printableWidth = pageSize.Width - (m.Left + m.Right); 
    if (printableWidth < printableHeight) { 
    if (labelSize.Width < labelSize.Height) { 
     float r1 = (printableWidth)/labelSize.Width; 
     float r2 = (printableHeight)/labelSize.Height; 
     scale = (r1 < r2) ? r1 : r2; 
    } else { 
     scale = (printableWidth)/labelSize.Width; 
    } 
    } else { 
    if (labelSize.Width < labelSize.Height) { 
     scale = (printableHeight)/labelSize.Height; 
    } else { 
     float r1 = (printableWidth)/labelSize.Width; 
     float r2 = (printableHeight)/labelSize.Height; 
     scale = (r1 < r2) ? r1 : r2; 
    } 
    } 
    float lh = scale * labelSize.Height; 
    float lw = scale * labelSize.Width; 
    float ml = scale * m.Left; 
    float mt = scale * m.Top; 
    Graphics G = e.Graphics; 
    G.SmoothingMode = smoothMode; 
    G.TextRenderingHint = TextRenderingHint.AntiAlias; 
    for (int i = 0; i < LabelsHorizontal; i++) { 
    float dx = i * (lw + ml); // Horizontal shift * scale 
    for (int j = 0; j < LabelsVertical; j++) { 
     float dy = j * (lh + mt); // Vertical shift * scale 
     #region ' Panels ' 
     foreach (Panel item in panels) { 
     float h = scale * item.Size.Height; 
     float w = scale * item.Size.Width; 
     float x = (ml + dx) + scale * item.Location.X; 
     float y = (mt + dy) + scale * item.Location.Y; 
     using (SolidBrush b = new SolidBrush(item.BackColor)) { 
      G.FillRectangle(b, x, y, w, h); 
     } 
     using (Pen p = new Pen(Brushes.Black)) { 
      G.DrawRectangle(p, x, y, w, h); 
     } 
     } 
     #endregion 
     #region ' Logo ' 
     if (logo != null) { 
     float h = scale * logo.Height; 
     float w = scale * logo.Width; 
     float x = (ml + dx) + scale * logoPt.X; 
     float y = (mt + dy) + scale * logoPt.Y; 
     G.DrawImage(logo, x, y, w, h); 
     } 
     #endregion 
     #region ' Labels ' 
     foreach (Label item in labels) { 
     float h = scale * item.Size.Height; 
     float w = scale * item.Size.Width; 
     float x = (ml + dx) + scale * item.Location.X; 
     float y = (mt + dy) + scale * item.Location.Y; 
     Color c = PrintPreview.Document.DefaultPageSettings.Color ? item.ForeColor : Color.Black; 
     Font font = new Font(item.Font.FontFamily, scale * item.Font.Size, item.Font.Style); 
     using (SolidBrush b = new SolidBrush(c)) { 
      StringFormat format = GetStringFormatFromContentAllignment(item.TextAlign); 
      format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; 
      format.Trimming = StringTrimming.None; 
      PointF locationF = new PointF(x, y); 
      SizeF size = new SizeF(w, h); 
      RectangleF r = new RectangleF(locationF, size); 
      G.DrawString(item.Text, font, b, r, format); 
     } 
     } 
     #endregion 
     #region ' Barcodes ' 
     foreach (AcpBarcodeControl item in barcodes) { 
     Image img = item.GetBarcodeImage(item.BarcodeText); 
     if (img != null) { 
      float h = scale * item.Size.Height; 
      float w = scale * item.Size.Width; 
      float x = (ml + dx) + scale * item.Location.X; 
      float y = (mt + dy) + scale * item.Location.Y; 
      G.DrawImage(img, x, y, w, h); 
     } 
     } 
     #endregion 
     labelQtyPrinted++; 
     if (labelQtyPrinted == PrintPreview.Document.PrinterSettings.Copies) { 
     e.HasMorePages = false; 
     return; 
     } 
    } 
    e.HasMorePages = (labelQtyPrinted < PrintPreview.Document.PrinterSettings.Copies); 
    } 
} 

所有的一切,它工作得很好。 “远离打印机”异常从不抛出。

那么,为什么有这么多的副本呢?

打印机是HP LaserJet 4050,如果这有什么区别。

+0

@约翰·桑德斯:你为什么从我的标题中拿出“C#”? – jp2code 2012-04-23 20:45:52

+1

因为你应该使用标签而不是标题来更好地识别(分类)你的问题。请参阅[我们应该何时从标题中删除伪标记](http://meta.stackexchange.com/questions/61055/when-should-we-remove-pseudo-tags-from-a-title) – Steve 2012-04-23 21:36:29

+0

@Steve是否正确。我通常不会向1000人以上的用户发表演讲,但标签是标签的地方;而不是标题。 – 2012-04-23 23:46:52

回答

3

我知道了!

Yippie!好吧,如果有人在乎,这里是协议:我需要每页打印两(2)个标签。

我要做的是计算打印多少页,使用垂直和水平打印的标签数量。

我加入了可变labelsRequested,改变现有的变量labelQtyPrinted被称为labelsPrinted

private int labelsPrinted; 
private int labelsRequested; 

我的公共Print方法更改为此:

public int Print(string docName, int rows, int columns, int copies) { 
    LabelsHorizontal = rows; 
    LabelsVertical = columns; 
    if (!String.IsNullOrEmpty(docName)) { 
    PrintPreview.Document.DocumentName = docName; 
    } 
    labelsRequested = copies; 
    //PrintPreview.Document.PrinterSettings.Copies = (short)copies; 
    PrintPreview.SettingsFilename = Settings.PageSettingsLocation; 
    if (!PrintPreview.PrinterSelected) { 
    if (PrintPreview.ShowPrinterSelectDialog() != DialogResult.OK) { 
     return 0; 
    } 
    } 
    if (ShowPrintPreview) { 
    Size docSize = PrintPreview.Document.DefaultPageSettings.Bounds.Size; 
    float height = 0.8F * Screen.PrimaryScreen.WorkingArea.Size.Height; 
    float width = (height * docSize.Width)/docSize.Height; 
    Size winSize = new Size((int)width, (int)height); 
    PrintPreview.Height = winSize.Height; 
    PrintPreview.Width = winSize.Width; 
    PrintPreview.Document.PrinterSettings.Copies = (short)labelsRequested; // this may cause problems 
    PrintPreview.ShowDialog(); 
    } else { 
    PrintPreview.PrintDocument(); 
    } 
    return labelsPrinted; 
} 

现在,而不是添加print_Click事件处理程序像我以前,我已经连线DocumentBeginPrintEndPrint像这样:

void Document_BeginPrint(object sender, PrintEventArgs e) { 
    labelsPrinted = 0; 
    float fPerPage = LabelsHorizontal * LabelsVertical; 
    if (1 < fPerPage) { 
    float fQty = labelsRequested; 
    float fTotal = fQty/fPerPage; 
    PrintPreview.Document.PrinterSettings.Copies = (short)fTotal; 
    } 
} 

void Document_EndPrint(object sender, PrintEventArgs e) { 
    Printed = (labelsPrinted == labelsRequested); 
} 

这里的关键,但是,显然来自我试图设置在PrintPage事件处理HasMorePages值。

“为什么?”你问。因为我只打印同一张大小文档的多个副本。 如果我的一个文档是跨越多个页面,那么我需要确保设置了HasMorePages

事不宜迟,这里是我的PrintPage事件处理(注意,很多这样的代码是非常普遍的,可以很容易地编辑为别人工作):

private void Document_Printed(object sender, PrintPageEventArgs e) { 
    float scale; 
    SizeF pageSize = new SizeF(
    PrintPreview.Document.DefaultPageSettings.PaperSize.Width, 
    PrintPreview.Document.DefaultPageSettings.PaperSize.Height 
); 
    Margins m = PrintPreview.Document.DefaultPageSettings.Margins; 
    float printableHeight = pageSize.Height - (m.Top + m.Bottom); 
    float printableWidth = pageSize.Width - (m.Left + m.Right); 
    if (printableWidth < printableHeight) { 
    if (labelSize.Width < labelSize.Height) { 
     float r1 = printableWidth/labelSize.Width; 
     float r2 = printableHeight/labelSize.Height; 
     scale = (r1 < r2) ? r1 : r2; 
    } else { 
     scale = printableWidth/labelSize.Width; 
    } 
    } else { 
    if (labelSize.Width < labelSize.Height) { 
     scale = (printableHeight)/labelSize.Height; 
    } else { 
     float r1 = printableWidth/labelSize.Width; 
     float r2 = printableHeight/labelSize.Height; 
     scale = (r1 < r2) ? r1 : r2; 
    } 
    } 
    float lh = scale * labelSize.Height; 
    float lw = scale * labelSize.Width; 
    float ml = scale * m.Left; 
    float mt = scale * m.Top; 
    Graphics G = e.Graphics; 
    G.SmoothingMode = smoothMode; 
    G.TextRenderingHint = TextRenderingHint.AntiAlias; 
    for (int i = 0; (i < LabelsHorizontal) && !e.Cancel; i++) { 
    float dx = i * (lw + ml); // Horizontal shift * scale 
    for (int j = 0; (j < LabelsVertical) && !e.Cancel; j++) { 
     float dy = j * (lh + mt); // Vertical shift * scale 
     #region ' Panels ' 
     foreach (Panel item in panels) { 
     float h = scale * item.Size.Height; 
     float w = scale * item.Size.Width; 
     float x = (ml + dx) + scale * item.Location.X; 
     float y = (mt + dy) + scale * item.Location.Y; 
     using (SolidBrush b = new SolidBrush(item.BackColor)) { 
      G.FillRectangle(b, x, y, w, h); 
     } 
     using (Pen p = new Pen(Brushes.Black)) { 
      G.DrawRectangle(p, x, y, w, h); 
     } 
     } 
     #endregion 
     #region ' Logo ' 
     if (logo != null) { 
     float h = scale * logo.Height; 
     float w = scale * logo.Width; 
     float x = (ml + dx) + scale * logoPt.X; 
     float y = (mt + dy) + scale * logoPt.Y; 
     G.DrawImage(logo, x, y, w, h); 
     } 
     #endregion 
     #region ' Labels ' 
     foreach (Label item in labels) { 
     float h = scale * item.Size.Height; 
     float w = scale * item.Size.Width; 
     float x = (ml + dx) + scale * item.Location.X; 
     float y = (mt + dy) + scale * item.Location.Y; 
     Color c = PrintPreview.Document.DefaultPageSettings.Color ? item.ForeColor : Color.Black; 
     Font font = new Font(item.Font.FontFamily, scale * item.Font.Size, item.Font.Style); 
     using (SolidBrush b = new SolidBrush(c)) { 
      StringFormat format = GetStringFormatFromContentAllignment(item.TextAlign); 
      format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; 
      format.Trimming = StringTrimming.None; 
      PointF locationF = new PointF(x, y); 
      SizeF size = new SizeF(w, h); 
      RectangleF r = new RectangleF(locationF, size); 
      G.DrawString(item.Text, font, b, r, format); 
     } 
     } 
     #endregion 
     #region ' Barcodes ' 
     foreach (AcpBarcodeControl item in barcodes) { 
     Image img = item.GetBarcodeImage(item.BarcodeText); 
     if (img != null) { 
      float h = scale * item.Size.Height; 
      float w = scale * item.Size.Width; 
      float x = (ml + dx) + scale * item.Location.X; 
      float y = (mt + dy) + scale * item.Location.Y; 
      G.DrawImage(img, x, y, w, h); 
     } 
     } 
     #endregion 
     labelsPrinted++; 
    } 
    } 
} 
+1

这是怎么得到的呢? ?当我发现这一点时,我正在寻求帮助来做同样的事情。 谢谢! – 2016-05-13 15:48:38

+0

谢谢,@dev_JORD。我很高兴别人有用它了! – jp2code 2016-05-14 03:00:02