报表打印时的页眉与多页格式设置问题求助
解决方案
1. 优化Logo加载逻辑
把Logo读取逻辑移到打印事件外部,避免每页重复连接数据库和读取文件,提升打印效率:
private Image _headerLogo; // 在窗体初始化/加载时执行一次 private void Form_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()) { string imagePath = @"Immagini\" + rdr["VALORE"].ToString(); if (File.Exists(imagePath)) { _headerLogo = Image.FromFile(imagePath); } } sqlite.Close(); }
2. 实现分页打印与每页页眉
通过跟踪打印进度、计算每页可容纳内容,确保每页都绘制页眉且内容自动分页:
// 跟踪当前已打印的文本行索引 private int _currentLineIndex = 0; // 存储拆分后的打印文本行 private List<string> _printLines = new List<string>(); // 打印前预处理文本内容 private void PreparePrintContent() { _printLines.Clear(); _currentLineIndex = 0; // 拆分RichTextBox内容为单行列表 _printLines.AddRange(richTextBox1.Lines); } private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { // 绘制当前页页眉 DrawHeader(e.Graphics); // 设置内容打印区域(避开页眉区域,预留100px给页眉) float marginLeft = e.MarginBounds.Left; float marginTop = e.MarginBounds.Top + 100; Font contentFont = new Font("Courier New", 14, FontStyle.Bold); float lineHeight = contentFont.GetHeight(e.Graphics); // 计算每页可容纳的最大行数 int maxLinesPerPage = (int)((e.MarginBounds.Height - 100) / lineHeight); // 逐行打印内容 int linesPrinted = 0; while (_currentLineIndex < _printLines.Count && linesPrinted < maxLinesPerPage) { string line = _printLines[_currentLineIndex]; e.Graphics.DrawString(line, contentFont, Brushes.Black, new PointF(marginLeft, marginTop + linesPrinted * lineHeight)); linesPrinted++; _currentLineIndex++; } // 判断是否需要打印下一页 e.HasMorePages = _currentLineIndex < _printLines.Count; } // 独立的页眉绘制方法,每页都会调用 private void DrawHeader(Graphics g) { // 打印Logo(如果已加载) if (_headerLogo != null) { g.DrawImage(_headerLogo, 50, 0, 100, 100); } // 打印报表标题 g.DrawString("Report Movimenti in Uscita non Pagati", new Font("Courier New", 18, FontStyle.Bold), Brushes.Black, new PointF(210, 40)); } // 修改打印按钮事件,先预处理内容再打印 private void button1_Click(object sender, EventArgs e) { PreparePrintContent(); printDocument1.DefaultPageSettings.Landscape = true; if (printPreviewDialog1.ShowDialog() == DialogResult.OK) { printDocument1.Print(); } } private void printPreviewDialog1_Load(object sender, EventArgs e) { printDocument1.DefaultPageSettings.Landscape = true; }
关键说明
- 页眉复用:将页眉绘制逻辑封装为独立方法,确保每一页打印时都会执行页眉绘制。
- 分页控制:通过
_currentLineIndex跟踪已打印的内容行,结合每页最大行数计算,自动触发多页打印。 - 性能优化:Logo仅在初始化时读取一次,避免重复的数据库操作和文件IO。
内容的提问来源于stack exchange,提问作者Gianluca Bendinelli
相关产品推荐
相关产品推荐

