能否将条码列表以MemoryStream存入Hashtable?多条码PDF生成报错
问题描述
需求:读取以下CSV文件,根据Position字段生成对应Item的CODE_128条码,并将条码放置在PDF页面的指定位置。
Item,Position A,1 B,5 C,7
当前问题:将生成的条码以MemoryStream形式存入Hashtable后,调用GeneratePDF方法时抛出Cannot access a closed stream异常,但单条码生成PDF的逻辑可正常运行。询问该批量生成方案是否可行?
相关代码
批量生成条码存入Hashtable的代码
while (!parser.EndOfData) { fields = parser.ReadFields(); string item = fields[0]; int position = Convert.ToInt32(fields[1]); BarcodeWriter writer = new BarcodeWriter() { Format = BarcodeFormat.CODE_128, Options = new EncodingOptions { Height = 100, Width = 300, PureBarcode = false, Margin = 10, }, }; string item = @"*" + item + "*"; var bitmap = writer.Write(item); bitmap.SetResolution(300,300); //bitmap.Save(@"E:\Image.png", System.Drawing.Imaging.ImageFormat.Png); using (MemoryStream ms = new MemoryStream()) { bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); hastable.Add(position, ms); } } GeneratePDF(hastable);
GeneratePDF方法代码
PdfDocument document = new PdfDocument(); // Create an empty page PdfPage page = document.AddPage(); // Get an XGraphics object for drawing XGraphics gfx = XGraphics.FromPdfPage(page); MemoryStream ms = new MemoryStream(); string filename = "Barcode.pdf"; foreach (DictionaryEntry values in hashtable) { int position = Convert.ToInt32(values.Key); ms = (MemoryStream)values.Value; XImage pic = XImage.FromStream(ms); pic.Interpolate = false; string points = getCoordinates(position); string[] axis = points.Split(','); int x = Convert.ToInt32(axis[0]); int y = Convert.ToInt32(axis[1]); gfx.DrawImage(pic, x, y, pic.PointWidth, pic.PointHeight);
解决方案
这个批量生成方案完全可行,报错的核心原因是你用using块包裹了MemoryStream:当using块执行结束时,流会被自动关闭,后续在GeneratePDF中访问已关闭的流就会触发异常。
修复步骤
替换流存储为字节数组(更安全)
避免直接存储MemoryStream,转而将流内容转为字节数组存入Hashtable,需要使用时再重建流。这样可以彻底规避流生命周期管理的问题:- 批量生成部分修改:
while (!parser.EndOfData) { fields = parser.ReadFields(); string item = fields[0]; int position = Convert.ToInt32(fields[1]); BarcodeWriter writer = new BarcodeWriter() { Format = BarcodeFormat.CODE_128, Options = new EncodingOptions { Height = 100, Width = 300, PureBarcode = false, Margin = 10, }, }; // 修复重复定义变量问题 item = @"*" + item + "*"; var bitmap = writer.Write(item); bitmap.SetResolution(300,300); using (MemoryStream ms = new MemoryStream()) { bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); // 存储字节数组而非流 hastable.Add(position, ms.ToArray()); } bitmap.Dispose(); // 释放Bitmap资源 } GeneratePDF(hastable); - GeneratePDF方法修改:
PdfDocument document = new PdfDocument(); PdfPage page = document.AddPage(); XGraphics gfx = XGraphics.FromPdfPage(page); string filename = "Barcode.pdf"; foreach (DictionaryEntry values in hashtable) { int position = Convert.ToInt32(values.Key); byte[] imageBytes = (byte[])values.Value; // 使用时重建流 using (MemoryStream ms = new MemoryStream(imageBytes)) { XImage pic = XImage.FromStream(ms); pic.Interpolate = false; string points = getCoordinates(position); string[] axis = points.Split(','); int x = Convert.ToInt32(axis[0]); int y = Convert.ToInt32(axis[1]); gfx.DrawImage(pic, x, y, pic.PointWidth, pic.PointHeight); } } // 补充PDF保存和资源释放 document.Save(filename); document.Dispose();
- 批量生成部分修改:
其他必改细节
- 原批量代码中存在重复定义
string item的错误,需要删除string item = @"*" + item + "*";里的string关键字; - 生成PDF后必须调用
document.Save和document.Dispose,否则无法得到完整的PDF文件,还会造成内存泄漏。
- 原批量代码中存在重复定义
修改完成后,批量生成条码并插入PDF指定位置的逻辑即可正常运行。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

