You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#与Microsoft.Office.Interop.Excel实现Excel自动化:图片插入问题

解决C# Excel自动化导出数据库图片(byte[])的问题

首先你的代码存在一处明显错误:循环里的excelWorksheet = excelWorkbook.Sheets[i] as Worksheet;会错误切换工作表,而非填充当前行的单元格数据。以下是修复后并支持图片导出的完整实现:

修改后的完整代码

string currentdatetime = DateTime.Now.ToString("yyyyMMddHHmmss");
string connectionString = Settings.Default["ConnectionString"].ToString();
string queryString = Settings.Default["Query"].ToString();
SaveFileDialog save = new SaveFileDialog();
save.OverwritePrompt = true;
save.Filter = "Excel 文件 |.xlsx| Excel 文件 |.xls";

// 修复逻辑判断:用&&替代||,避免空值/空字符串误判
if (!string.IsNullOrEmpty(Settings.Default.Query))
{
    if (save.ShowDialog() == DialogResult.OK)
    {
        try
        {
            Application excelApp = new Application();
            Workbook excelWorkbook = excelApp.Workbooks.Add();
            Worksheet excelWorksheet = excelWorkbook.Worksheets[1];

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(queryString, connection))
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        // 写入表头
                        int col = 1;
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            excelWorksheet.Cells[1, col].Value2 = reader.GetName(i);
                            // 自动调整列宽(可选优化)
                            excelWorksheet.Columns[col].AutoFit();
                            col++;
                        }

                        // 写入数据行
                        int row = 2;
                        while (reader.Read())
                        {
                            col = 1;
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                var fieldValue = reader[i];
                                if (fieldValue is DBNull)
                                {
                                    excelWorksheet.Cells[row, col].Value2 = string.Empty;
                                }
                                else if (fieldValue is byte[] imageBytes)
                                {
                                    // 处理数据库中的图片字节数据
                                    using (MemoryStream ms = new MemoryStream(imageBytes))
                                    {
                                        Image img = Image.FromStream(ms);
                                        // 在对应单元格位置插入图片
                                        var shape = excelWorksheet.Shapes.AddPicture(
                                            ms,
                                            Microsoft.Office.Core.MsoTriState.msoFalse,
                                            Microsoft.Office.Core.MsoTriState.msoTrue,
                                            excelWorksheet.Cells[row, col].Left,
                                            excelWorksheet.Cells[row, col].Top,
                                            img.Width,
                                            img.Height
                                        );
                                        // 设置图片随单元格移动、调整大小
                                        shape.Placement = Microsoft.Office.Interop.Excel.XlPlacement.xlMoveAndSize;
                                    }
                                    // 调整行高适配图片
                                    excelWorksheet.Rows[row].Height = excelWorksheet.Cells[row, col].Height * (img.Height / excelWorksheet.Cells[row, col].Height);
                                }
                                else
                                {
                                    // 普通数据类型直接写入单元格
                                    excelWorksheet.Cells[row, col].Value2 = fieldValue;
                                }
                                col++;
                            }
                            row++;
                        }
                    }
                }
            }

            // 保存并清理Excel资源
            excelWorkbook.SaveAs(save.FileName);
            excelWorkbook.Close();
            excelApp.Quit();
            // 释放COM对象,避免Excel进程后台残留
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorksheet);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkbook);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);

            using (FileStream stream = new FileStream(save.FileName, FileMode.Open))
            {
                ExcelSpread.LoadDocument(stream);
            }
            Cursor.Current = Cursors.Default;
        }
        catch (Exception exception)
        {
            MessageBox.Show(exception.Message);
        }
    }
}
else
{
    if (XtraMessageBox.Show("请先从数据库设置选项卡的查询编写区域输入要使用的查询语句。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning) == DialogResult.OK)
    {
        Forms.WriteQuery wq = new Forms.WriteQuery();
        wq.Show();
    }
}

关键修改说明

  • 修复逻辑判断:将原错误的||改为!string.IsNullOrEmpty,避免空值/空字符串的误判。
  • 图片处理逻辑:判断字段值是否为byte[],通过MemoryStream转换为Image后,调用Shapes.AddPicture插入到对应单元格位置。
  • 图片适配优化:设置图片随单元格移动、调整大小,同时自动调整行高适配图片尺寸。
  • COM资源释放:添加Marshal.ReleaseComObject释放Excel相关COM对象,防止后台残留Excel进程。

注意事项

  • 确保项目已引用Microsoft.Office.Interop.Excel程序集。
  • 数据库中的byte[]必须是有效的图片格式(如JPG、PNG),否则Image.FromStream会抛出异常。
  • 若图片体积过大,建议先压缩再插入,避免Excel文件体积超标。

内容的提问来源于stack exchange,提问作者Ahmet Enes Söylemez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:47:36