printdocument添加空白页 [英] printdocument adds blank page

查看:128
本文介绍了printdocument添加空白页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用printdocument从数据库中打印数据,但我将其打印到指定范围内的数据打印位置,但仍然有2处出错

I'm trying to print data from a database using printdocument and i got it to where it prints the data from the specified range but there are still 2 things that go wrong

仍然无法按预期运行的事物是

the things that still don't work like intended are

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

这是我必须调用printdocument的代码

this is the code i have to call the 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); }
}

这是打印文档的代码

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 + " "; }
}

推荐答案

您写道,您使用了来自网络的资源,我想它显示了.我们都这样做,但是对它们的质量相当怀疑是非常重要的.当然,将两种来源结合起来很可能根本行不通.

You wrote that you have used sources from the web and I guess it shows. We all do that but it is really important to be rather suspicious about their quality. And of course combining two sources most likely will not work at all..

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

I'll first go over a couple of issues with your code and then show you an example of how to print items from a DB on several pages..

请帮个忙,请谨慎选择变量的名称!是的,相信我,这会花更长的时间,但它会付出代价. (而且,如果您无法提出令人信服的任何内容,请退后!这通常表明您对问题的理解不够充分.)

Please do yourself a favor and chose the names of your variables with care! Yes, that takes a little longer but it will pay, believe me. (And if you can't come up with anything convincing, step back! This is usually an indication that you don't understand the problem well enough..)

让我们看一下:有currentY,这非常好.还有itemperpagetotalnumberamount,它们都很糟糕!他们要么完全不清楚,要么甚至具有误导性!

Let's look at some: There is currentY, which is pretty good. And there are itemperpage, totalnumber and amount, all of which are terrible! They either are totally unclear or even misleading!

让我们用名字更好的几个吧:

Let's set up a few ones with better names:

// 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

另一个问题是您选择的单位,或者确切地说是缺乏选择的单位.默认 GraphicsUnit Display,用于打印时为1/100英寸.如果您愿意,我建议以代码形式编写以对其进行记录.该单元将在整个布局过程中使用,因此它应该在代码中可见!我个人更喜欢毫米.还有其他几个单位.选择您的单位,但要记录下来!

Another issue is the unit you chose, or to be precise the lack of choosing one. The default GraphicsUnit is Display which for printing amounts to 1/100 inch. If you like that I suggest to write it in code to document it. This unit will be used during the whole layout process so it should be visible in the code! I personally prefer Millimeters. There are several other units..pick yours but document it!

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

One more thing you should look into are String.Format() and string.PadLeft(). They are so much nicer than the loop you have in the tostring() method!

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

Now let's look at your specific problems:

一旦我们使用了足够多的名称而实际上却不了解它们就可以理解的变量,那么工作结束时页面为空的变量就会消失.

The one with an empty page at the end of the job will go away once we use enough variables with names one can actually understand without learning them..

另一个问题是设置DB读取的方式:您需要在开始打印的位置而不是在PrintPage循环中设置读取器.注意:这些实际上是两个循环:一个可见为while (...reader.Read() ),另一个是外部循环隐含:整个PrintPage事件本身就是循环主体

The other problem is the way you set up the DB-reading: You need to set up the reader where you start the printing and not in the PrintPage loop. Note: These actually are two loops: one is visible as the while (...reader.Read() ) and the other, outer loop is implict: The whole PrintPage event itself is the loop body.

首先让我们看一下range()代码.我已经将它变成一个返回最大记录数的函数.第一步,我获取了计数.然后,我设置了DataReader进行实际阅读,这将在PrintPage事件中发生:我枚举了字段,因此我可以控制它们的顺序,并且不提取不需要的东西.

First let's look at the range() code. I have turned it into a function that returns the maximum number of records. I fetch the count in a first step. Then I set up the DataReader for the real reading, which will happen in the PrintPage event: I enumerate the fields so I have control over their order and don't pull in stuff I don't need.

请注意,我使用的是MySql,但是类几乎相同,只是带有MySQl-前缀.我没有在此处包含连接代码.当然,我是从我自己的数据库中读取的.

Note that I am using MySql but the classes are pretty much the same, just with a MySQl-prefix. I don't include the connect code here. And of course I read from a database of my own..

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

现在,让我们使用上面的变量来查看打印命令:

Now let's look at the print command, using the variables from above:

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调用中创建的!

Note that the Reader is created in the range call!

最后是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);
    }
}

这篇关于printdocument添加空白页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆