如何将Yogesh.ExcelXmlWorkBook转换为字节数组并存入数据库?
解决方法
要把Yogesh.ExcelXmlWorkbook转换成字节数组并存入数据库,你可以通过**内存流(MemoryStream)**替代文件系统捕获导出内容,再将流转换为字节数组,最后用参数化SQL把字节数组写入数据库。
步骤1:修改导出逻辑生成字节数组
原代码是调用book.Export(string path)写入本地文件,我们改用内存流接收导出的XML内容,再转成byte[]:
// 替换原有的book.Export(...)代码 byte[] excelBytes; using (var ms = new MemoryStream()) { book.Export(ms); // 若Yogesh.ExcelXmlWorkbook不直接支持导出到Stream,用下面的替代方案 // 替代方案:先导出到字符串再转字节 // using (var sw = new StringWriter()) // { // book.Export(sw); // excelBytes = Encoding.UTF8.GetBytes(sw.ToString()); // } excelBytes = ms.ToArray(); }
步骤2:将字节数组存入数据库
用参数化SQL避免注入风险,假设你的数据库表包含ReportCode(报表编码)和ExcelData(存储二进制内容)字段,ExcelData类型设为VARBINARY(MAX):
string connString = System.Configuration.ConfigurationSettings.AppSettings["YourConnString"].ToString(); using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); string sql = @"INSERT INTO YourTableName (ReportCode, ExcelData) VALUES (@ReportCode, @ExcelData); SELECT SCOPE_IDENTITY();"; // 可选:返回新增记录ID using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@ReportCode", reportCode); cmd.Parameters.Add("@ExcelData", SqlDbType.VarBinary, -1).Value = excelBytes; // 执行插入并获取新增ID(如果不需要可直接用ExecuteNonQuery) int newRecordId = Convert.ToInt32(cmd.ExecuteScalar()); } }
完整修改后的方法示例
下面是整合后的完整代码,将原方法改为直接生成字节数组并存入数据库,返回新增记录的ID方便后续使用:
public static int SaveExcelToDatabase(int reportCode, SqlDataReader sqlReader, bool hasHeader) { int savedRecordId = 0; try { ExcelXmlWorkbook book = new ExcelXmlWorkbook(); book.Properties.Author = "Raahabr"; Yogesh.ExcelXml.Worksheet sheet = book[0]; sheet.Name = ""; sheet.FreezeTopRows = 4; int startCol = 3; int currentRow = 3; int colCount = sqlReader.FieldCount; // 处理表头 if (hasHeader) { ReportBOL rbol = new ReportBOL(); Dictionary<string, string> cNames = rbol.getColumnNames(reportCode); for (int i = 0; i < colCount; i++) { string head = sqlReader.GetName(i); string value = cNames.ContainsKey(head) ? cNames[head] : head; if (string.IsNullOrEmpty(value)) value = head; sheet[currentRow + i, currentRow].Value = value; sheet[currentRow + i, currentRow].Border.LineStyle = Borderline.Continuous; sheet[currentRow + i, currentRow].Border.Sides = BorderSides.All; } } currentRow++; // 处理数据行 if (sqlReader.HasRows) { while (sqlReader.Read()) { for (int i = 0; i < colCount; i++) { sheet[startCol + i, currentRow].Value = sqlReader[i].ToString(); sheet[startCol + i, currentRow].Border.LineStyle = Borderline.Continuous; sheet[startCol + i, currentRow].Border.Sides = BorderSides.All; } currentRow++; } } // 生成Excel二进制数组 byte[] excelBytes; using (var ms = new MemoryStream()) { book.Export(ms); excelBytes = ms.ToArray(); } // 存入数据库 string connString = System.Configuration.ConfigurationSettings.AppSettings["YourConnString"].ToString(); using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); string sql = @"INSERT INTO ReportExcelData (ReportCode, ExcelContent) VALUES (@ReportCode, @ExcelContent); SELECT SCOPE_IDENTITY();"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@ReportCode", reportCode); cmd.Parameters.Add("@ExcelContent", SqlDbType.VarBinary, -1).Value = excelBytes; savedRecordId = Convert.ToInt32(cmd.ExecuteScalar()); } } book.DeleteSheet(0); } catch (Exception ex) { // 保留你的异常日志逻辑 // System.IO.File.WriteAllText(..., ex.ToString()); } finally { sqlReader.Close(); sqlReader.Dispose(); } return savedRecordId; }
注意事项
- 确认
Yogesh.ExcelXmlWorkbook的Export方法支持写入Stream,若仅支持文件路径或TextWriter,就用StringWriter捕获内容再转字节。 - 数据库字段优先用
VARBINARY(MAX),不要用已废弃的IMAGE类型。 - 必须使用参数化SQL,杜绝注入风险。
内容的提问来源于stack exchange,提问作者PEDRAM POURHAKIM
相关产品推荐
相关产品推荐

