Visual Studio WinForm报表打印:横向设置及每页页眉/logo问题求助
Windows Forms报表打印优化方案:横向布局、分页、每页重复页眉/Logo
针对你的需求,我们分三个核心点修改代码:
1. 设置页面横向方向
直接在打印前设置PrintDocument的页面方向为横向,可放在按钮点击事件里:
private void button1_Click(object sender, EventArgs e) { // 设置页面为横向 printDocument1.DefaultPageSettings.Landscape = true; if (printPreviewDialog1.ShowDialog() == DialogResult.OK) { printDocument1.Print(); } }
2. 确保每页重复显示页眉和Logo
PrintPage事件会在每一页打印时触发一次,所以只要把绘制Logo和页眉的代码放在这个事件里,每页都会自动重复渲染。但注意不要每次都查询数据库,提前缓存Logo路径能提升性能:
- 添加类级别的变量缓存Logo路径和打印进度:
private string _logoPath; private int _currentPrintCharIndex = 0; // 记录当前打印到的文本位置,用于分页
- 在窗体加载时预加载Logo路径(避免每次打印都操作数据库):
private void YourForm_Load(object sender, EventArgs e) { sqlite.Open(); string stm = "SELECT VALORE FROM IMPOSTAZIONI WHERE IMPOSTAZIONE = 'LOGO';"; using var cmd = new SQLiteCommand(stm, sqlite); using SQLiteDataReader rdr = cmd.ExecuteReader(); if (rdr.Read()) { _logoPath = @"Immagini\" + rdr["VALORE"].ToString(); } sqlite.Close(); }
3. 处理RichTextBox内容的分页
直接调用DrawString打印整个文本不会自动分页,需要通过Graphics.MeasureString计算每页可显示的内容,配合HasMorePages属性实现多页打印:
修改后的PrintPage事件完整代码:
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { // 1. 绘制Logo和页眉(每页都会执行) if (!string.IsNullOrEmpty(_logoPath) && File.Exists(_logoPath)) { using Image bgFront = Image.FromFile(_logoPath); e.Graphics.DrawImage(bgFront, 0, 0, 100, 100); } // 绘制页眉标题 var headerFont = new Font("Courier New", 18, FontStyle.Bold); e.Graphics.DrawString("Report Movimenti in Uscita non Pagati", headerFont, Brushes.Black, new PointF(160, 40)); // 2. 计算内容打印区域(避开页眉,从Y=150开始,预留页边距) var contentRect = new RectangleF( e.MarginBounds.Left, 150, e.MarginBounds.Width, e.MarginBounds.Height - (150 - e.MarginBounds.Top) ); var contentFont = new Font("Courier New", 14, FontStyle.Bold); var stringFormat = new StringFormat(); int charsFitted, linesFilled; // 计算当前页能容纳的字符数 e.Graphics.MeasureString( richTextBox1.Text.Substring(_currentPrintCharIndex), contentFont, contentRect.Size, stringFormat, out charsFitted, out linesFilled ); // 打印当前页的内容 e.Graphics.DrawString( richTextBox1.Text.Substring(_currentPrintCharIndex, charsFitted), contentFont, Brushes.Black, contentRect, stringFormat ); // 更新已打印的字符位置 _currentPrintCharIndex += charsFitted; // 判断是否还有剩余内容需要打印下一页 if (_currentPrintCharIndex < richTextBox1.Text.Length) { e.HasMorePages = true; } else { // 重置索引,避免下次打印从上次位置开始 _currentPrintCharIndex = 0; e.HasMorePages = false; } }
关键说明
- 每页的Logo和页眉会自动重复,因为
PrintPage事件每页触发时都会执行绘制代码 - 分页逻辑通过记录
_currentPrintCharIndex跟踪打印进度,配合MeasureString计算每页容量 - 提前缓存Logo路径避免重复数据库操作,提升打印效率
内容的提问来源于stack exchange,提问作者Gianluca Bendinelli
相关产品推荐
相关产品推荐

