使用PrintDocument将DataTable中的每一行打印到单独的页面

本文关键字:打印 一行 单独 PrintDocument DataTable 使用 | 更新日期: 2023-09-27 18:15:57

我有一个DataTable的应用程序,我需要将DataTable中的每一行打印到一个单独的页面,我有一个地狱的时间试图让它工作。我发现了很多关于打印多于一页打印DataGridViews的帖子,但我找不到任何关于在DataTable中打印每一行到单独的页面的内容。

无论如何,这是我到目前为止把它放在一起,它不太工作。

private void btnPrint_Click(object sender, EventArgs e)
{
    printTag.DefaultPageSettings.Landscape = true;
    PrintPreviewDialog preview = new PrintPreviewDialog();
    preview.Document = printTag;
    preview.Show();
}
private void printTag_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    PrintRow = 0;
    //Here I set my Fonts, String Formats and Pen Styles
    int maxRows = _dtTags.Rows.Count;
    for (int lines = 0; lines < maxRows; ++lines)
    {
        PrintRow++;
        if (PrintRow >= _dtTags.Rows.Count)
        {
            e.HasMorePages = PrintRow < _dtTags.Rows.Count;
            return; //Done Printing
        }
        var row = _dtTags.Rows[PrintRow];
        //Pass data from current Row of DataTable to variables which are used to populate the e.Graphic
        jobNum = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job");
        machInfo = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job Desc");
        jobNote = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job Note");
        color = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Color");
        parts = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Parts");
        empName = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Employee");
        //Here my e.Graphic is created, located and filled out
    }
}

那么,上面的代码是这样处理的:

  1. 如果我的表只有一行,打印预览显示为空白。
  2. 如果我的表有多行,最后一行不打印。
  3. 表中的每一行(最后一行除外,如果只有一行)打印在同一页上。

所以基本上我的预览看起来就像我把同一张纸多次放进打印机,然后在上面打印。

任何帮助或建议让这个工作将非常感激。

使用PrintDocument将DataTable中的每一行打印到单独的页面

看来你误解了PrintPage事件是如何工作的。PrintPage事件中的e.HasMorePages指示是否应该打印一个额外的页面,以及是否应该再次引发PrintPage事件。

  • 设置e.HasMorePages的逻辑是错误的@rleffler指出。

    PrintRow++;
    if (PrintRow >= _dtTags.Rows.Count)
    {
        e.HasMorePages = PrintRow < _dtTags.Rows.Count;
        return; //Done Printing
    }
    

    e。HasMorePages永远不能用您的逻辑设置为true,因此将永远不会打印超过一页。

  • PrintRow号必须在打印前重置,不能在PrintPage事件中重置。

  • 无需在PrintPage事件中迭代DGV行,只需获得与其索引对应的当前行(在这种情况下PrintRow值为-1)。

private void btnPrint_Click(object sender, EventArgs e)
{
    printTag.DefaultPageSettings.Landscape = true;
    PrintPreviewDialog preview = new PrintPreviewDialog();
    // Reset before printing
    PrintRow = 0;
    preview.Document = printTag;
    preview.Show();
}

private void printTag_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    //Here I set my Fonts, String Formats and Pen Styles
    int maxRows = _dtTags.Rows.Count;
    if (maxRows == 0) {
        return;
    }
    PrintRow++;
    e.HasMorePages = PrintRow < _dtTags.Rows.Count;
    int lines = PrintRow - 1;
    var row = _dtTags.Rows(lines);
    //Pass data from current Row of DataTable to variables which are used to populate the e.Graphic
    jobNum = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job");
    machInfo = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job Desc");
    jobNote = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Job Note");
    color = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Color");
    parts = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Parts");
    empName = _dsTags.Tables["Paint Tags"].Rows[lines].Field<string>("Employee");
    //Here my e.Graphic is created, located and filled out

}

问题部分出在你的逻辑上。

        if (PrintRow >= _dtTags.Rows.Count)
        {
            e.HasMorePages = PrintRow < _dtTags.Rows.Count;
            return; //Done Printing
        }

这是唯一可以设置e.HasMorePages的地方。如果PrintRow大于或等于_dtTags的行数,那么设置e.HasMorePages的语句将始终为假,因为它会询问PrintRow是否小于该行数。当hasmorepages设置为true并返回时,将导致处理程序再次被调用。如果你想要更多的页面,那么你需要在某个地方将其设置为true,当你想要停止打印时将其设置为false。你的主要问题是e.s hasmorepages永远不能用你的逻辑设置为true,因此永远不会打印多于一个页面。