我必须为我们公司生产的产品打印运输标签。
为了帮助自己了解这些标签的结果,我使用 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;
}
我必须编写一个自定义的 PrintPreview 类,它以PrintPreviewDialog
为基类,以便我可以用这个printButton_Click方法覆盖它的 Print 按钮:
// 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,如果这有什么不同的话。