SQL数据库分页打印问题求助:重复打印前15行无法实现正确分页
SQL数据库分页打印问题求助:重复打印前15行无法实现正确分页
兄弟,我瞅你这分页打印的问题,根源在于每次触发新页面打印时,DataReader都会重新从头读取数据,结果第二页又重复打前15条了!咱们得换个思路,先把要打印的数据一次性缓存到内存里,这样就能精准控制每一页该打印哪部分内容了。
我给你捋个解决方案,分两步走:
第一步:先把所有要打印的数据缓存起来
DataReader是向前只读的,没法跳转到指定位置继续读取,所以咱们先把数据库里的数据全读出来存到集合里,比如用自定义实体类或者字典,这样后续分页打印时直接从内存里取就行,不用再反复查数据库。
示例代码(用实体类更规范):
// 全局变量:缓存打印数据+记录当前打印到哪一条 private List<PrintItem> _printItems = new List<PrintItem>(); private int _currentPrintIndex = 0; private readonly int _itemsPerPage = 15; // 每页15条 // 打印前先加载数据的方法 private void LoadPrintData() { // 替换成你的数据库连接字符串 using (var conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); string sql = "SELECT cCode, cName, cShortAddress, cPhone FROM 你的表名"; using (var cmd = new SqlCommand(sql, conn)) { using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) { _printItems.Add(new PrintItem { Code = rdr["cCode"].ToString(), Name = rdr["cName"].ToString(), ShortAddress = rdr["cShortAddress"].ToString(), Phone = rdr["cPhone"].ToString() }); } } } } } // 自定义实体类,用来存每条打印数据 public class PrintItem { public string Code { get; set; } public string Name { get; set; } public string ShortAddress { get; set; } public string Phone { get; set; } }
如果不想写实体类,用字典也可以,把上面的PrintItem换成Dictionary<string, string>就行,加载数据时往字典里存对应字段。
第二步:修改打印事件逻辑,精准控制分页
在打印事件里,咱们从_currentPrintIndex开始打印,每打一条就更新这个索引,满15条就标记还有下一页,直到所有数据打完。
示例打印事件代码:
private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e) { int yPos = 182; int itemsPrinted = 0; // 从当前索引开始,打印满一页或者数据打完为止 while (_currentPrintIndex < _printItems.Count && itemsPrinted < _itemsPerPage) { var currentItem = _printItems[_currentPrintIndex]; // 绘制内容,和你原来的逻辑一致 e.Graphics.DrawString(currentItem.Code, new Font("Arial", 11, FontStyle.Regular), Brushes.Black, new Point(60, yPos)); e.Graphics.DrawString(currentItem.Name, new Font("Arial", 11, FontStyle.Regular), Brushes.Black, new Point(120, yPos)); e.Graphics.DrawString(currentItem.ShortAddress, new Font("Arial", 11, FontStyle.Regular), Brushes.Black, new Point(310, yPos)); e.Graphics.DrawString(currentItem.Phone, new Font("Arial", 11, FontStyle.Regular), Brushes.Black, new Point(580, yPos)); yPos += 22; itemsPrinted++; _currentPrintIndex++; } // 判断是否还有未打印的数据,标记是否需要下一页 e.HasMorePages = _currentPrintIndex < _printItems.Count; // 打印完所有数据后重置索引,方便下次打印 if (!e.HasMorePages) { _currentPrintIndex = 0; } }
为啥这样能解决问题?
- 数据缓存到内存后,不用每次分页都重新读数据库,避免了DataReader从头开始的问题;
_currentPrintIndex记录了当前打印到哪一条,下一页直接从这个位置继续,不会重复打印前15条;- 逻辑更清晰,也方便后续调整每页打印条数或者修改打印格式。
你可以试试这个方案,应该能解决你的分页重复问题!
备注:内容来源于stack exchange,提问作者Minhaz Tuhin
相关产品推荐
相关产品推荐

