3

我必须为我们公司生产的产品打印运输标签。

为了帮助自己了解这些标签的结果,我使用 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,如果这有什么不同的话。

4

1 回答 1

3

我知道了!

伊皮!

好的,如果有人在乎,这里是交易:我需要每页打印两 (2) 个标签。

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

我添加了变量并更改了要调用labelsRequested的现有变量:labelQtyPrintedlabelsPrinted

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我没有像以前那样添加事件处理程序,而是将Document's连接起来BeginPrintEndPrint如下所示:

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);
}

不过,这里的关键显然来自我试图在事件处理程序中设置HasMorePages值。PrintPage

“为什么?” 你问。因为我只打印多份相同的 1 页大小的文档。如果我的一个文档要跨越多个页面,那么我需要确保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++;
    }
  }
}
于 2012-04-24T21:36:54.043 回答