用C#的printdocument画了一个表格,表格有31排,里面需要填入数据,数据的长短不定,有的没有超过31排,有的超过31排。
没有超过31排的,显示没有问题。
超过31排,也就是数据超过一页的,就不能正常显示了
也看到有人说用e.HasMorePages = true来解决,但是自己理解的不是很透彻,如果内容超过了31排,也就是超过了一页,用了e.HasMorePages = true后,显示的内容不仅填入到第一页的表格外面,而且也没有第二页的内容显示出来,代码如下:
if (totalpages == 1)
{
for (int i = 0; i < r; i++)
{
g.DrawString(arr[i], myfont1, mybrush, x + 615, y + 215 + i * 18);
}
}
if (totalpages == 2)
{
for (int i = 0; i < 31; i++)
{
g.DrawString(arr[i], myfont1, mybrush, x + 615, y + 215 + i * 18);
}
e.HasMorePages = true;
for (int i = 31; i < r; i++)
{
g.DrawString(arr[i], myfont1, mybrush, x + 615, y + 215 + i * 18);
}
e.HasMorePages = false;
}
你需要在打印文档的PrintPage事件处理函数中进行分页处理。具体来说,需要使用PrintPageEventArgs.HasMorePages属性来指示是否还有更多的页面要打印。
每当需要打印新的一页时,应该将HasMorePages设置为true,并绘制该页的内容。接下来,在下一次调用PrintPage事件处理函数时,可以继续绘制下一页的内容。当不需要再打印更多页面时,将HasMorePages设置为false。
例如,可以这样实现分页处理:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
// 定义变量表示当前页的编号、每页的行数和当前已经打印的行数
int page = 1;
int rowsPerPage = 31;
int rowsPrinted = 0;
// 创建用于绘制文本的字体
Font font = new Font("Arial", 10);
// 计算总页数
int totalPages = (int)Math.Ceiling((double)arr.Length / rowsPerPage);
// 绘制当前页的内容
while (rowsPrinted < rowsPerPage && page <= totalPages)
{
for (int i = rowsPrinted; i < arr.Length; i++)
{
e.Graphics.DrawString(arr[i], font, Brushes.Black, new PointF(615, 215 + i * 18));
rowsPrinted++;
}
page++;
// 如果还有更多的页面要打印,设置HasMorePages为true
if (page <= totalPages)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
}
}
以下是在你的代码的基础上进行修改的代码:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
// 定义变量表示当前页的编号、每页的行数和当前已经打印的行数
int page = 1;
int rowsPerPage = 31;
int rowsPrinted = 0;
// 创建用于绘制文本的字体
Font font = new Font("Arial", 10);
// 计算总页数
int totalPages = (int)Math.Ceiling((double)arr.Length / rowsPerPage);
// 循环打印每一页
while (page <= totalPages)
{
// 绘制当前页的内容
for (int i = rowsPrinted; i < arr.Length; i++)
{
e.Graphics.DrawString(arr[i], font, Brushes.Black, new PointF(615, 215 + i * 18));
rowsPrinted++;
// 如果已经绘制的行数达到了每页的行数,跳出循环
if (rowsPrinted >= rowsPerPage)
{
break;
}
}
page++;
// 如果还有更多的页面要打印,设置HasMorePages为true
if (page <= totalPages)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
}
}
在这个代码中,我们使用了一个循环来打印所有的页面,并在每一页中绘制行的内容。每当绘制完每一页的内容后,我们将页码加1,并检查是否还有更多的页面要打印。如果有,我们将HasMorePages设置为true,否则设置为false。
当设置了e.HasMorePages = true,会触发PrintPage事件,然后PrintDocument会继续调用PrintPage事件处理函数。需要在这个事件处理函数中处理打印的下一页内容。
代码中,当totalpages==2时,在绘制了前31行后,立即设置e.HasMorePages = true,然后再继续绘制后面的行,这样是错误的。应该将e.HasMorePages设置为false,然后在下一次的PrintPage事件中,绘制剩余的行。
可以将代码修改为如下的形式:
int currentRow = 0;
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics;
if (totalpages == 1)
{
for (int i = currentRow; i < r; i++)
{
g.DrawString(arr[i], myfont1, mybrush, x + 615, y + 215 + i * 18);
currentRow++;
}
}
if (totalpages == 2)
{
for (int i = currentRow; i < 31; i++)
{
g.DrawString(arr[i], myfont1, mybrush, x + 615, y + 215 + i * 18);
currentRow++;
}
e.HasMorePages = true;
}
}
private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
currentRow = 0;
}
这样在PrintPage事件中,可以从currentRow开始绘制剩余的行,而不是从0开始。然后当处理完所有的行后,设置e.HasMorePages为false,告诉PrintDocument打印已经结束。
在这里,可以使用PrintDocument的EndPrint事件来将currentRow的值设置回0,以便下一次打印
仅供参考,望采纳,谢谢。
在 C# 中,你可以使用 .NET Framework 中的 PrintDocument 类来实现多页打印和预览。
首先,你需要创建一个 PrintDocument 对象,并设置它的 PrintPage 事件,这个事件会在每一页打印时触发。在这个事件的处理函数中,你可以使用 e.Graphics 对象的绘图方法来绘制你的页面内容。你还需要设置 PrintDocument 对象的 DefaultPageSettings 属性,以指定打印机的纸张大小和方向等信息。
下面是一个简单的例子,展示了如何使用 PrintDocument 类实现一个简单的打印预览功能:
using System.Drawing.Printing;
// ...
PrintDocument printDocument = new PrintDocument();
printDocument.DefaultPageSettings.Landscape = true;
printDocument.DefaultPageSettings.PaperSize = new PaperSize("A4", 827, 1170);
printDocument.PrintPage += PrintPage;
PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
printPreviewDialog.Document = printDocument;
printPreviewDialog.ShowDialog();
// ...
private void PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString("Hello, World!", new Font("Arial", 12), Brushes.Black, new PointF(0, 0));
}
在这个例子中,我们创建了一个 PrintDocument 对象,并设置了它的打印方向和纸张大小。然后我们使用 PrintPage 事件来绘制页面内容,在这个事件的处理函数中,我们可以使用 e.Graphics 对象的绘图方法来绘制文本。最后,我们使用 PrintPreviewDialog 类来显示打印预览
如果你想要实现多页打印,你需要在 PrintPage 事件的处理函数中设置 e.HasMorePages 属性,以指示是否还有其他页需要打印。
例如,假设你想要打印一个包含多个字符串的列表,你可以这样实现:
private List<string> stringsToPrint = new List<string> { "Hello,", "World!", "This", "is", "a", "multi-page", "print", "example." };
private int currentStringIndex = 0;
private void PrintPage(object sender, PrintPageEventArgs e)
{
float yPos = 0f;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
string line = null;
Font printFont = new Font("Arial", 12);
SolidBrush brush = new SolidBrush(Color.Black);
// 字符循环,一个个打印
while (currentStringIndex < stringsToPrint.Count)
{
line = stringsToPrint[currentStringIndex];
yPos = topMargin + (currentStringIndex * printFont.GetHeight(e.Graphics));
e.Graphics.DrawString(line, printFont, brush, leftMargin, yPos, new StringFormat());
currentStringIndex++;
}
// 检查是否有多页需要打印
if (currentStringIndex < stringsToPrint.Count)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
}
在这个例子中,我们使用一个循环来逐个打印字符串列表中的字符串,并在每一次循环之后检查是否还有更多的字符串需要打印。如果还有,我们就将 e.HasMorePages 设置为 true,以便在下一次调用 PrintPage 事件时继续打印剩余的内容。
希望能帮助到你!
推荐使用html to pdf 的方式,这样设置更加灵活,具体参考下面的文章