printdocument添加空白页面

时间:2015-02-20 08:54:28

标签: c# sql winforms printing printdocument

我正在尝试使用printdocument从数据库打印数据,并将其打印到指定范围内打印数据的位置,但仍有两件事情出错

仍然无法正常工作的事情是

  • 在打印时,如果页面几乎被完全使用,则会添加一个空白页面,上面只打印一个标题
  • 如果页面已满,则下一页将再次从该范围的第一项开始(使用多个列表进行修复,因为我无法弄清楚如何使用子列表创建列表)

这是我必须调用printdocument的代码

private void button3_Click(object sender, EventArgs e)//print
{
    range();
    try
    {
        if (artikel == true)
        {
            itemperpage = totalnumber = 0;
            printPreviewDialog1.Document = printDocument1;
            print = true;
            printDocument1.Print();
            // this.Close();
        }
    }
    catch (Exception q) { MessageBox.Show("" + q); }
}

这是printdocument的代码

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    if (artikel == true)
    {
        Font messageFont = new Font("Arial", 14, System.Drawing.GraphicsUnit.Point);

        float currentY = 10;// declare  one variable for height measurement 
        e.Graphics.DrawString("                                                                                                                  I N K O O P A R T I K E L E N ", DefaultFont, Brushes.Black, 10, currentY);//this will print one heading/title in every page of the document 
        currentY += 15;

        SqlCommand artprint = new SqlCommand("select * from ART WHERE ART BETWEEN @range AND @range2 ORDER BY ART ASC", Connectie.connMEVO_ART);
        if (comboBox1.SelectedIndex <= comboBox2.SelectedIndex)
        {
            artprint.Parameters.Add("@range", SqlDbType.VarChar).Value = comboBox1.SelectedItem;
            artprint.Parameters.Add("@range2", SqlDbType.VarChar).Value = comboBox2.SelectedItem;
        }
        else if (comboBox2.SelectedIndex <= comboBox1.SelectedIndex)
        {
            artprint.Parameters.Add("@range", SqlDbType.VarChar).Value = comboBox2.SelectedItem;
            artprint.Parameters.Add("@range2", SqlDbType.VarChar).Value = comboBox1.SelectedItem;
        }
        drART = artprint.ExecuteReader();
        try
        {
            while (totalnumber <= amount - 1 && drART.Read())
            {// check the number of items 
                tostring();//SQL data to string
                row = row + Environment.NewLine + "ART            LEV         LTD       MVRD   SGR        INK        CRNI    " + " VALUTA    KOR ";
                row = row + Environment.NewLine + aa + "  " + a + "  " + b + "  " + c + "  " + d + "  " + m + "  " + f + "   " + g + "          " + h;
                row = row + Environment.NewLine + "EH2     EH1      EF            OMS     ";
                row = row + Environment.NewLine + j + "         " + k + "         " + l + "  " + i;
                row = row + Environment.NewLine;
                e.Graphics.DrawString(row, DefaultFont, Brushes.Black, 50, currentY);//print each item
                Debug.WriteLine("" + row);
                row = "";
                currentY += 80; // set a gap between every item
                totalnumber += 1; //increment count by 1
                if (itemperpage <= 12) 
                {
                    itemperpage += 1; // increment itemperpage by 1
                    e.HasMorePages = false; // set the HasMorePages property to false , so that no other page will not be added 
                }
                else // if the number of item(per page) is more than 12 then add one page 
                {
                    itemperpage = 0; //initiate itemperpage to 0 .  
                    e.HasMorePages = true; //e.HasMorePages raised the PrintPage event once per page .           
                    return;//It will call PrintPage event again   
                }
            }
        }
        catch (Exception ef)
        {
            MessageBox.Show("" + ef);
        }
        artprint.Dispose();
    }
}

private void tostring()
{
    aa = drART["ART"].ToString();
    for (int ss = aa.Length; ss < 8; ss++) { aa = aa + " "; }
    a = drART["LEV"].ToString();
    for (int ss = a.Length; ss < 10; ss++) { a = a + " "; }
    b = drART["LTD"].ToString();
    for (int ss = b.Length; ss < 10; ss++) { b = b + " "; }
    c = drART["MVRD"].ToString();
    for (int ss = c.Length; ss < 10; ss++) { c = c + " "; }
    d = drART["SGR"].ToString();
    for (int ss = d.Length; ss < 10; ss++) { d = d + " "; }
    m = drART["INK"].ToString();
    for (int ss = m.Length; ss < 10; ss++) { m = m + " "; }
    f = drART["CRNI"].ToString();
    for (int ss = f.Length; ss < 10; ss++) { f = f + " "; }
    g = drART["VALUTA"].ToString();
    for (int ss = g.Length; ss < 3; ss++) { g = g + " "; }
    h = drART["KOR"].ToString();
    for (int ss = h.Length; ss < 10; ss++) { h = h + " "; }
    i = drART["OMS"].ToString();
    j = drART["EH2"].ToString();
    for (int ss = j.Length; ss < 3; ss++) { j = j + " "; }
    k = drART["EH1"].ToString();
    for (int ss = k.Length; ss < 3; ss++) { k = k + " "; }
    l = drART["EF"].ToString();
    for (int ss = l.Length; ss < 10; ss++) { l = l + " "; }
}

1 个答案:

答案 0 :(得分:2)

您写道,您已经使用了来自网络的资源,我猜它会显示出来。我们都这样做但是对它们的质量非常怀疑是非常重要的。当然,结合两种来源很可能根本不起作用。

我将首先介绍您的代码中的几个问题,然后向您展示如何在几个页面上从数据库中打印项目的示例..

请帮个忙,谨慎选择变量的名称!是的,这需要更长的时间,但它会支付,相信我。 (如果你不能提出任何令人信服的信息,请退后一步!这通常表明你不能很好地理解这个问题。)

让我们看一下:有currentY,这是非常好的。有itemperpagetotalnumberamount,所有这些都很糟糕!他们要么完全不清楚,要么误导!

让我们设置几个更好的名字:

// layout variables
int itemsPerPage = 40;  // how many items fit on one page
int itemHeight = 25;    // height of one item in the chosen unit

// print job variables
int totalNumber = -1;   // total number of records/items coming from the dbms
int itemsToPrint = 75;  // total number of items we want to print

// print progress variables
int itemsPrinted = 0;   // number of items printed so far
int pagesPrinted = 0;   // number of pages printed

另一个问题是你选择的单位,或者确切地说是缺乏选择单位。默认GraphicsUnitDisplay,打印金额为1/100英寸。如果你喜欢我建议用代码写它来记录它。该单元将在整个布局过程中使用,因此它应该在代码中可见!我个人更喜欢毫米。还有其他几个单位..挑选你的,但记录下来!

您应该考虑的另一件事是String.Format()string.PadLeft()。它们比tostring()方法中的循环好得多!

现在让我们来看看你的具体问题:

一旦我们使用了足够的变量和一个人们可以理解的名字而没有学习它们,那么在作业结束时空页面的那个将会消失。

另一个问题是您设置数据库读取的方式:您需要将读卡器设置为开始打印而不是PrintPage循环。注意:这些实际上是两个循环:一个是while (...reader.Read() )可见,另一个是外循环暗示:整个PrintPage事件本身是循环体。

首先让我们看一下range()代码。我把它变成了一个返回最大记录数的函数。我在第一步获取计数。然后我为真实阅读设置了DataReader,这将发生在PrintPage事件中:我列举了字段,因此我可以控制他们的顺序,而不是拉入我不需要的东西

请注意,我使用的是MySql,但这些类几乎相同,只有MySQl - 前缀。我这里不包含连接代码。当然,我从我自己的数据库中读到..

MySqlConnection DBC = new MySqlConnection("");
MySqlCommand CMD = null;
MySqlDataReader DR = null;

int range ()
{
    CMD = new MySqlCommand("select count(0) from test.artists ", DBC);
    var count = CMD.ExecuteScalar();
    int counter = Convert.ToInt32(count);
    CMD = new MySqlCommand("select artist_ID, artist, genres from test.artists ", DBC);
    DR = CMD.ExecuteReader();
    return (int)counter;
}

现在让我们看一下print命令,使用上面的变量:

private void cb_print_Click(object sender, EventArgs e)
{
    totalNumber = range();
    try
    {
        if (DBC.State == ConnectionState.Open)
        {
            pagesPrinted = 0;
            printPreviewDlg.Document = printDocument1;
            printPreviewDlg.ShowDialog();
        }
    } catch (Exception q) { MessageBox.Show("" + q); }
    DR.Dispose();
}

请注意,Reader已在range来电中创建了

最后是PrintPage事件:

private void printDocument1_PrintPage(object sender, 
                            System.Drawing.Printing.PrintPageEventArgs e)
{
    // my page unit
    e.Graphics.PageUnit = GraphicsUnit.Millimeter;

    // starting a new page
    int itemsOnPage = 0;
    pagesPrinted++;

    float currentY = 12;
    e.Graphics.DrawString(String.Format(
               "HEADER -  printing {0} items of {1}    - Page {2}",
               itemsToPrint, totalNumber, pagesPrinted), 
               Font, Brushes.Black, 1, currentY);  

    currentY += 30;  // header height

    try
    {
        // page is not full and we want to print more items
        while (itemsOnPage < itemsPerPage && itemsPrinted < itemsToPrint - 1
               && DR.Read())
        {
            string row = String.Format("{0,5:000} Artist: {1,20}  ({2})   ",
                                         DR[0], DR[1], DR[2]);

            e.Graphics.DrawString(row, DefaultFont, Brushes.Black, 50, currentY);  
            // Console.WriteLine("" + row);

            currentY += itemHeight; 
            itemsPrinted++; 
            itemsOnPage++;

            // we want to print more items but now the page is full
            if ( itemsPrinted < itemsToPrint && itemsOnPage >= itemsPerPage)
            {
                itemsOnPage = 0;        
                e.HasMorePages = true;         
                return;                 
            }
            else 
            {
                // this will only be used after all data are printed
                e.HasMorePages = false; 
            }
        }
    } catch (Exception ef)
    {
        MessageBox.Show("" + ef);
    }
}