简体   繁体   English

WinForms - 打印两个数据网格视图时,打印预览很好,但在纸上只打印第二个 dgv

[英]WinForms - When printing two datagridviews, print preview is good but on paper only 2nd dgv is printed

I am making a software to help me at work.我正在制作一个软件来帮助我工作。 It reads two excel (xlsx) files and get some info from them.它读取两个 excel (xlsx) 文件并从中获取一些信息。 Then it put the info in one of the two datagridviews or in both datagridviews.然后它将信息放在两个datagridviews 之一或两个datagridviews 中。

Then i have a number that i need to show when i print the datagridviews.然后我有一个数字,当我打印 datagridviews 时需要显示。 In print preview all is exactly as i want but when printing on paper it removes (or doesn't remember) everything about first datagridview and anything i print with it and start from the 2nd datagridview.在打印预览中,一切都完全符合我的要求,但是在纸上打印时,它会删除(或不记得)关于第一个 datagridview 的所有内容以及我用它打印的所有内容,并从第二个 datagridview 开始。

Here how it shows in print preview:这是它在打印预览中的显示方式:

打印预览

but when i print it on paper i get like this但是当我把它打印在纸上时,我会变成这样

印在纸上

Why the first datagridview gone on paper but if i print it PDF from Microsoft print to PDF i get PDF that has exactly as the preview.为什么第一个 datagridview 出现在纸上,但如果我从 Microsoft 打印 PDF 到 PDF,我得到的 PDF 与预览完全相同。

Problem only when printing on paper.仅在纸张上打印时出现问题。

Here is my printing code https://pastebin.com/6ZF2FevZ这是我的打印代码https://pastebin.com/6ZF2FevZ

using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Text;
using System.Linq;
using System.Windows.Forms;

namespace Motabaka
{
  class DGVsPrinter
  {
      private Font fontD;
      private Brush brushD = Brushes.Black;
      private bool dgv1Finished;
      private string a3800, a1800;

      public string Title { get; set; }
      public bool IncludeDateAndTimeInFooter { get; set; }
      public bool IncludePageNumberInFooter { get; set; }
      public bool IncludeEndingPhraseAtTheEnd { get; set; }
      public string EndingPhrase { get; set; } = "End";

      private DataGridView dataGridView1, dataGridView2;
      private int rowIndex;
      private int cellCount;
      private int pageNumber = 1;
      private readonly PrintDocument printDoc;
      private int iTotalWidth1;
      private int iTotalWidth2;
      private Dictionary<int, int> ColumntWidths;
      private Dictionary<int, int> arrColumnWidths1 = new Dictionary<int, int>();
      private Dictionary<int, int> arrColumnWidths2 = new Dictionary<int, int>();
      private bool preview;

      public DGVsPrinter(DataGridView dataGridView1, DataGridView dataGridView2, PrintDocument printDoc, string A3800, string A1800)
      {
          this.dataGridView1 = dataGridView1;
          this.dataGridView2 = dataGridView2;
          this.printDoc = printDoc;
          fontD = new Font(dataGridView1.Font, FontStyle.Bold);

          printDoc.BeginPrint += OnBeginPrint;
          printDoc.PrintPage += OnPrintPage;
          a3800 = A3800;
          a1800 = A1800;
      }

      public void Print(bool preview = false)
      {
          this.preview = preview;

          rowIndex = 0;
          cellCount = 0;
          pageNumber = 0;

          var dgvs = new DataGridView[] { dataGridView1, dataGridView2 };
          foreach (DataGridView dgv in dgvs)
          {
              var rows = dgv.Rows
              .Cast<DataGridViewRow>()
              .FirstOrDefault(r => !r.IsNewRow && r.Visible);

              if (rows != null)
                  cellCount = rows.Cells
                      .Cast<DataGridViewCell>()
                      .Where(c => c.Visible)
                      .Count();

              if (cellCount == 0)
              {
                  //MessageBox.Show(new Form() { FormBorderStyle = FormBorderStyle.None }, "Nothing to print...");
                  continue;
              }
          }

          if (cellCount == 0)
          {
              MessageBox.Show(new Form() { FormBorderStyle = FormBorderStyle.None }, "Nothing to print...");
              return;
          }

          if (preview)
          {
              try
              {
                  using (var pd = new PrintPreviewDialog())
                  {
                      pd.Document = printDoc;
                      pd.ShowDialog();
                  }
              }
              catch (Exception ex)
              {
                  Error.Log(ex);
              }
          }
          else
          {
              try
              {
                  using (var pd = new PrintDialog())
                  {
                      pd.Document = printDoc;
                      if (pd.ShowDialog() == DialogResult.OK)
                      {
                          pd.Document.Print();
                      }
                  }
              }
              catch (Exception ex)
              {
                  Error.Log(ex);
              }
          }
      }

      private void OnBeginPrint(object sender, PrintEventArgs e)
      {
          try
          {
              rowIndex = 0; pageNumber = 1;
              iTotalWidth1 = 0;
              iTotalWidth2 = 0;
              arrColumnWidths1.Clear();
              arrColumnWidths2.Clear();

              foreach (DataGridViewColumn dgvGridCol in dataGridView1.Columns)
              {
                  if (!dgvGridCol.Visible) { continue; }

                  iTotalWidth1 += dgvGridCol.Width;
              }

              foreach (DataGridViewColumn dgvGridCol in dataGridView2.Columns)
              {
                  if (!dgvGridCol.Visible) { continue; }

                  iTotalWidth2 += dgvGridCol.Width;
              }
          }
          catch (Exception ex)
          {
              Error.Log(ex, "Error while printing [OnBeginPrint]");
          }
      }

      private void OnPrintPage(object sender, PrintPageEventArgs e)
      {
          try
          {
              e.Graphics.Clear(Color.White);

              var w = e.MarginBounds.Width / cellCount;
              var x = e.MarginBounds.X;
              var y = e.MarginBounds.Y;
              int h;
              Rectangle rec;

              while (true)
              {
                  var dgv = !dgv1Finished ? dataGridView1 : dataGridView2;
                  ColumntWidths = (dgv == dataGridView1) ? arrColumnWidths1 : arrColumnWidths2;
                  var totalWidths = (dgv == dataGridView1) ? iTotalWidth1 : iTotalWidth2;

                  var iTmpWidth = 0;
                  if (pageNumber == 1)
                  {
                      for (int i = dgv.Columns.Count - 1; i >= 0; i--)
                      {
                          DataGridViewColumn GridCol = dgv.Columns[i];

                          if (!GridCol.Visible) continue;

                          iTmpWidth = (int)(Math.Floor(GridCol.Width /
                                         (double)totalWidths * totalWidths *
                                         (e.MarginBounds.Width / (double)totalWidths)));

                          if (!ColumntWidths.Keys.Contains(GridCol.Index))
                          {
                              ColumntWidths.Add(GridCol.Index, iTmpWidth);
                          }
                      }
                  }

                  using (var sf = new StringFormat())
                  {
                      sf.Alignment = StringAlignment.Center;
                      sf.LineAlignment = StringAlignment.Center;
                      
                      sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
                      sf.Trimming = StringTrimming.None;

                      e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                      // Uncomment to print the headers in the first page only.
                      //if (pageNumber == 1)
                      //{
                      h = dgv.RowTemplate.Height + 20;

                      #region Title
                      var TextToDraw = dgv.Tag?.ToString();
                      var xCenter = e.MarginBounds.Left + e.MarginBounds.Width / 2;

                      e.Graphics.DrawString(TextToDraw, fontD, brushD, xCenter, y - 20, sf);
                      #endregion

                      using (var strf = new StringFormat())
                      {
                          strf.Alignment = StringAlignment.Far;
                          strf.LineAlignment = StringAlignment.Near;

                          #region Amount
                          var amount = (dgv == dataGridView1) ? a1800 : a3800;
                          var XC = e.MarginBounds.Right;
                          var font = new Font(dgv.Font.FontFamily, 12f, FontStyle.Regular);

                          e.Graphics.DrawString(amount, font, brushD, XC, y - 20, strf);
                          #endregion
                      }

                      for (int i = dgv.Columns.Count - 1; i >= 0; i--)
                      {
                          var col = dgv.Columns[i];

                          if (col.Visible)
                          {
                              w = ColumntWidths[col.Index];
                              rec = new Rectangle(x, y, w, h);

                              e.Graphics.FillRectangle(Brushes.AliceBlue, rec);
                              e.Graphics.DrawString(
                                  col.HeaderText,
                                  col.DataGridView.Font,
                                  Brushes.Black,
                                  rec,
                                  sf);
                              //Pen pen = new Pen(Color.Black, 1.3f);
                              //pen.Alignment = PenAlignment.Inset;
                              //e.Graphics.DrawRectangle(pen, rec);
                              Color[] colors;
                              if (false)
                              {
                                  colors = new Color[]
                                  {
              SystemColors.ControlDark,
              SystemColors.ControlDarkDark,
              SystemColors.ControlLightLight,
              SystemColors.ControlLight
                                  };
                              }
                              else
                              {
                                  colors = new Color[]
                                  {
              SystemColors.ControlLightLight,
              SystemColors.ControlLight,
              SystemColors.ControlDark,
              SystemColors.ControlDarkDark
                                  };
                              }
                              using (Pen p = new Pen(colors[0]))
                              {
                                  e.Graphics.DrawLine(p, rec.X, rec.Bottom - 1,
                                      rec.X, rec.Y);
                                  e.Graphics.DrawLine(p, rec.X, rec.Y,
                                      rec.Right - 1, rec.Y);
                              }
                              using (Pen p = new Pen(colors[1]))
                              {
                                  e.Graphics.DrawLine(p, rec.X + 1, rec.Bottom - 2,
                                      rec.X + 1, rec.Y + 1);
                                  e.Graphics.DrawLine(p, rec.X + 1, rec.Y + 1,
                                      rec.Right - 2, rec.Y + 1);
                              }
                              using (Pen p = new Pen(colors[2]))
                              {
                                  e.Graphics.DrawLine(p, rec.X, rec.Bottom - 1,
                                      rec.Right - 1, rec.Bottom - 1);
                                  e.Graphics.DrawLine(p, rec.Right - 1, rec.Bottom - 1,
                                      rec.Right - 1, rec.Y);
                              }
                              using (Pen p = new Pen(colors[3]))
                              {
                                  e.Graphics.DrawLine(p, rec.X + 1, rec.Bottom - 2,
                                      rec.Right - 2, rec.Bottom - 2);
                                  e.Graphics.DrawLine(p, rec.Right - 2, rec.Bottom - 2,
                                      rec.Right - 2, rec.Y + 1);
                              }

                              x += w;
                          }
                      }

                      x = e.MarginBounds.X;
                      y += h;
                      //}

                      /*Drawing the rows with their content*/
                      for (var i = rowIndex; i < dgv.RowCount; i++)
                      {
                          var row = dgv.Rows[i];

                          if (!row.Visible) continue;

                          if (row.IsNewRow) break;

                          h = GetRowHeight(e.Graphics, row, e.MarginBounds, sf);

                          if (h > e.MarginBounds.Height)
                          {
                              MessageBox.Show("Insufficient height.");
                              e.Cancel = true;
                              return;
                          }

                          /*Drawing row's cells with their content*/
                          for (int r = row.Cells.Count - 1; r >= 0; r--)
                          {
                              var cell = row.Cells[r];
                              if (!cell.Visible) { continue; }

                              w = ColumntWidths[cell.ColumnIndex];
                              rec = new Rectangle(x, y, w, h);

                              if (rec.Bottom > e.MarginBounds.Bottom)
                              {
                                  pageNumber++;
                                  rowIndex = i;
                                  e.HasMorePages = true;
                                  return;
                              }

                              var color = (cell.InheritedStyle.BackColor == Color.Yellow) ? new SolidBrush(SystemColors.Window) : new SolidBrush(cell.InheritedStyle.BackColor);
                              e.Graphics.FillRectangle(color, rec);
                              e.Graphics.DrawString(
                                  cell.FormattedValue.ToString(),
                                  dgv.Font,
                                  Brushes.Black,
                                  rec,
                                  sf);
                              e.Graphics.DrawRectangle(Pens.Black, rec);

                              x += rec.Width;
                          }/*Done drawing the cells in a row*/

                          x = e.MarginBounds.X;
                          y += h;
                      }/*Done drawing all the rows*/

                      #region Date and time
                      if (IncludeDateAndTimeInFooter)
                      {
                          var strDate = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();
                          var wdate = e.Graphics.MeasureString(strDate, fontD, e.MarginBounds.Height, sf).Width;
                          var hdate = e.Graphics.MeasureString(strDate, fontD, e.MarginBounds.Height, sf).Height;
                          
                          var yBottom = e.MarginBounds.Height + e.MarginBounds.Top;

                          var recDate = new Rectangle(e.MarginBounds.X, yBottom, e.MarginBounds.Width, (int)hdate);
                          //e.Graphics.FillRectangle(Brushes.LightSkyBlue, recDate);
                          e.Graphics.DrawRectangle(Pens.Black, recDate);
                          e.Graphics.DrawString(strDate, fontD, brushD, recDate.X, yBottom);
                      }
                      #endregion
                      #region Page Number
                      if (IncludePageNumberInFooter)
                      {
                          var pNumber = "Page " + pageNumber;
                          var yBottom = e.MarginBounds.Height + e.MarginBounds.Top;
                          
                          var xRight = e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(pNumber, fontD, e.MarginBounds.Width, sf).Width);

                          e.Graphics.DrawString(pNumber, fontD, brushD, xRight, yBottom);
                      }
                      #endregion

                      y = y + 70;
                      rowIndex = 0;
                      dgv1Finished = true;
                      e.HasMorePages = (dgv == dataGridView1);
                  }

                  if (!e.HasMorePages)
                  {
                      if (IncludeEndingPhraseAtTheEnd)
                      {
                          using (var strf = new StringFormat())
                          {
                              strf.LineAlignment = StringAlignment.Center;
                              strf.Alignment = StringAlignment.Center;
                              strf.FormatFlags = StringFormatFlags.DirectionRightToLeft;

                              var fontD = new Font(dgv.Font, FontStyle.Bold);
                              var brushD = Brushes.Black;
                              var xCenter = e.MarginBounds.Left + e.MarginBounds.Width / 2;
                              var yBottom = e.MarginBounds.Top
                                  + e.MarginBounds.Height
                                  + e.Graphics.MeasureString(EndingPhrase, fontD, e.MarginBounds.Height, strf).Height;

                              e.Graphics.DrawString(EndingPhrase, fontD, brushD, xCenter, y - 60, strf);
                          }
                      }

                      break;
                  }
              }
          }
          catch (Exception ex)
          {
              Error.Log(ex, " Error while printing [OnPrintPage]");
          }
      }

      private int GetRowHeight(
  Graphics g,
  DataGridViewRow row,
  Rectangle bounds,
  StringFormat sf,
  int minHeight = 22)
      {
          var cells = row.Cells.OfType<DataGridViewTextBoxCell>()
              .Where(c => c.Visible);

          if (cells == null) return minHeight;

          /*(longest, next) => next.Length > longest.Length ? next : longest*/
          var cell = cells.Aggregate((DataGridViewTextBoxCell)null, (x, y) => (x != null) && (!string.IsNullOrWhiteSpace(x.FormattedValue.ToString()) && !string.IsNullOrWhiteSpace(y.FormattedValue.ToString())) &&
          (x.FormattedValue.ToString().Length > y.FormattedValue.ToString().Length) ? x : y);


          if (cell == null) return minHeight;
          var h = g.MeasureString(cell.FormattedValue.ToString(),
              row.DataGridView.Font,
              new SizeF(ColumntWidths[cell.ColumnIndex], bounds.Height),
              sf).ToSize().Height;

          return Math.Max(h + 10, minHeight); // 6 for top and bottom margins...
      }


  }
}

I call the print like this我这样称呼印刷品

var print = new DGVsPrinter(dataGridView1, dataGridView2, printDocument1, Final3800L.Text, Final1800L.Text)
            {
                IncludeDateAndTimeInFooter = true,
                IncludePageNumberInFooter = true
            };
            print.Print(true);

I found the problem.我发现了问题。

If i print it by print dialog it prints good.如果我通过打印对话框打印它,它打印得很好。 But when i show the preview, this problem happens.但是当我显示预览时,就会出现这个问题。 Because i didn't set dgv1Finished to false on OnBeginPrint .因为我没有OnBeginPrint 上将 dgv1Finished设置为 false 。

when it actually prints It runs the code again and dgv1Finished is already true after the preview so it get datagridview2 first and nothing about datagridvie1.当它实际打印时它再次运行代码,并且 dgv1Finished 在预览之后已经是真的,所以它首先得到datagridview2,而没有关于datagridvie1。

I only have to set dgv1Finished = false in OnBeginPrint and now it prints everything.我只需要在OnBeginPrint中设置dgv1Finished = false ,现在它会打印所有内容。

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

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