Estoy haciendo un software que me ayude en el trabajo. Lee dos de excel (xlsx) archivos y obtener un poco de info de ellos. Luego se puso la información en uno de los dos datagridviews o en ambos datagridviews.
Entonces tengo un número que necesito mostrar al imprimir la datagridviews. En la vista previa de impresión todo es exactamente como yo quiero, sino cuando la impresión en papel se elimina (o no recuerdo) todo sobre el primer datagridview y nada puedo imprimir con ella y empezar a partir de la 2ª datagridview.
He aquí cómo se muestra en la vista previa de impresión:
pero cuando lo imprimo en papel puedo obtener como este
Por eso, el primer datagridview ido en el papel, pero si lo imprimo en PDF desde Microsoft imprimir a PDF puedo conseguir en PDF que tiene exactamente la vista previa.
Problema sólo cuando la impresión en papel.
Aquí está mi código de impresión 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...
}
}
}
Yo llame a la impresión como este
var print = new DGVsPrinter(dataGridView1, dataGridView2, printDocument1, Final3800L.Text, Final1800L.Text)
{
IncludeDateAndTimeInFooter = true,
IncludePageNumberInFooter = true
};
print.Print(true);