Add QR Codes in columns in Print Preview

Viewed 76

I have the following code and want to change to print the QRCodes in multiple columns on a A4 format page:

        private int curRow = 0;
        private int curCopy = 0;        
        private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            curRow = 0;
            curCopy = 0;
        }
        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            var curY = e.MarginBounds.Y;

            using (var fontNormal = new Font("Arial", 12))
            using (var sf = new StringFormat())
            {
                sf.Alignment = sf.LineAlignment = StringAlignment.Center;
                int itemHeight = (int)fontNormal.GetHeight(e.Graphics) + 10;


                for (int row = curRow; row < dt.Rows.Count; row++)
                {
                    DataRow dr = dt.Rows[row];

                    if (!string.IsNullOrEmpty(dr.Field<string>(1)) &&
                        int.TryParse(dr.Field<string>(4)?.ToString(), out int copies))
                    {
                        for (int i = curCopy; i < copies; i++)
                        {
                            var imgRect = new Rectangle(e.MarginBounds.X, curY, 200, 200);
                            var labelRect = new Rectangle(
                                imgRect.X,
                                imgRect.Bottom,
                                imgRect.Width,
                                itemHeight);

                            if (curY + imgRect.Height + labelRect.Height >= e.MarginBounds.Bottom)
                            {
                                curCopy = i;
                                e.HasMorePages = true;
                                return;
                            }

                            e.Graphics.DrawImage(GenerateQRCODE(dr[1].ToString()), imgRect);
                            e.Graphics.DrawString(dr[1].ToString(),
                                fontNormal, Brushes.Black,
                                labelRect, sf);

                            curY = labelRect.Bottom + 30;
                        }
                    }

                    curRow = row + 1;
                    curCopy = 0;
                }
            }
            refreshprintbtn.Enabled = true;
        }

Now the print preview is the following: link to screenthot

I generate more than 50 QRCodes, so if the A4 page is full with QRCodes, I want to start a new page. The same QRCode can appear several times and is based on the dr[4] value and the dr[1] is the value for the code.

1 Answers

The way you calculate the curY value to print in rows is the same way that you need to follow to calculate the x value to print in columns. Offset the x by the width of the image plus some space and break the row if the x value plus the image width is greater than the e.MarginBounds.Right value.

private int curRow = 0;
private int curCopy = 0;

private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
    curRow = curCopy = 0;
}

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
    var curX = e.MarginBounds.X;
    var curY = e.MarginBounds.Y;

    using (var fontNormal = new Font("Arial", 12))
    using (var sf = new StringFormat())
    {
        sf.Alignment = sf.LineAlignment = StringAlignment.Center;
        int itemHeight = (int)fontNormal.GetHeight(e.Graphics) + 10;

        for (int row = curRow; row < dt.Rows.Count; row++)
        {
            DataRow dr = dt.Rows[row];

            if (!string.IsNullOrEmpty(dr.Field<string>(1)) &&
                int.TryParse(dr.Field<string>(4)?.ToString(), out int copies))
            {
                for (int i = curCopy; i < copies; i++)
                {
                    var imgRect = new Rectangle(curX, curY, 200, 200);
                    var labelRect = new Rectangle(
                        imgRect.X,
                        imgRect.Bottom,
                        imgRect.Width,
                        itemHeight);

                    // You should do this to dispose of the
                    // image after printing it.
                    using (var qrImage = GenerateQRCODE(dr[1].ToString()))
                        e.Graphics.DrawImage(qrImage, imgRect);
                    e.Graphics.DrawString(dr[1].ToString(),
                        fontNormal, Brushes.Black,
                        labelRect, sf);

                    curX = imgRect.Right + 30;

                    if (curX + imgRect.Width > e.MarginBounds.Right)
                    {
                        curX = e.MarginBounds.X;
                        curY = labelRect.Bottom + 30;
                    }

                    if (curY + imgRect.Height + labelRect.Height >= e.MarginBounds.Bottom)
                    {
                        curCopy = i + 1;
                        e.HasMorePages = true;
                        return;
                    }
                }
            }

            curRow = row + 1;
            curCopy = 0;
        }
    }
    refreshprintbtn.Enabled = true;
}
Related