如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹

Posted

技术标签:

【中文标题】如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹【英文标题】:How to Read Image Data (storing word document) from SQL Server Table and save it to local folder 【发布时间】:2017-07-11 09:51:04 【问题描述】:

我想提取在 SQL 中存储为图像类型字段的 word 文档,并将每个单独的文档保存在本地文件夹中。存储在 sql 中的图像类型数据中的 doc 文件是特殊编码的 OLEObjects。 我先尝试一个,但我需要对表中的每条记录做同样的事情。这是我到目前为止所做的:

Byte[] bytData = null;
string constring = @"mystirngconnection";

 SqlCommand command = new SqlCommand(@"SELECT LongDescription FROM SuUserReport 
                                WHERE ProductId = 53 AND UserReportId = 31525");

 command.CommandType = CommandType.Text;

 SqlConnection myconn = new SqlConnection(constring);

 command.Connection = myconn;

 myconn.Open();

 using (SqlDataReader dr = command.ExecuteReader())
  
    while (dr.Read())
     
       bytData = (byte[])dr["LongDescription"];
     
  

if (bytData != null)
 
      FileStream fs = new FileStream("C:\\Temp\\Test1.doc", 
                                     FileMode.OpenOrCreate, FileAccess.Write);

                    BinaryWriter br = new BinaryWriter(fs);
                    br.Write(bytData, 0, bytData.Length);
                    fs.Dispose();
 

我基本上有两个问题:

读取这类数据非常慢 使用上面的代码适用于普通的word文档但是我表中的信息有OLEObject编码的信息,代码保存了一个word文档但信息只有encoded characters

以前,当使用链接到 longDescription 图像类型字段的 Access 绑定对象框架打开表单时,这些图像(word 文档)会直接从 SQL 打开。用户可以通过双击这个特殊框架来编辑文档。以下代码打开文档并使其可用于保存更改:

    With oleLongDescription
        .Verb = acOLEVerbOpen 'In a separate window
        .Action = acOLEActivate
    End With

有人能帮我解决这个问题吗?我不介意使用 c# 或 vb,只要它有效 =)。

【问题讨论】:

Reading SQL Varbinary Blob from Database的可能重复 您是否尝试过使用其他文件以确保文件没有损坏? OLEObjects 的问题在于它们不是正确的 Word 文件,而是带有额外页眉和页脚的 Word 文件。这篇文章解释了为什么您导出的“word 文件”无法打开,并给出了一些关于在哪里查看的提示:social.msdn.microsoft.com/Forums/vstudio/en-US/… 谢谢亚历克斯,是的,我发现它们是存储在 sql 中的图像列中的 OLEobjects,而不是普通的 word 文档,这就是为什么其他人可以直接在 c# 或 vba 中读取他们的文件,但我不能我需要使用这个可怕的 ole 对象以某种方式获取信息。非常感谢您的链接,它看起来与我试图实现的非常相似 =)。 【参考方案1】:

这是我用来打开 Blob 的代码。 byte[] myarray 是数据库中的 blob 字段,fileext 是您正在创建的文件的扩展名,filename 是您给它的名称。它会删除任何以前同名的文件。

 public static string Openfilefrombyte(byte[] myarray, string fileext, string filename)
    
        Computer myComputer = new Computer();

        string filenamef = myComputer.FileSystem.SpecialDirectories.Temp + @"\" + filename + "." + fileext;
        if (File.Exists(filenamef))
        
            File.Delete(filenamef);
        

        //save to file and open
        FileStream myfs = new FileStream(filenamef, FileMode.CreateNew);

        myfs.Write(myarray, 0, myarray.Length);
        myfs.Flush();
        myfs.Close();

        myfs = null;
        Process.Start(filenamef);

        return "OK";

    

【讨论】:

谢谢Haim,我保存文件没有问题,问题是字节或数据被编码了。我也在使用控制台应用程序,所以我没有 FileSystem.SpecialDirectories.Temp =( 您显然可以使用任何您想要的目录而不是 temp 目录,但您的主要问题是将所有 oleobjects 转换为 word 对象。我建议你添加这些标签词,也许你可以得到一些帮助。【参考方案2】:

我基本上有两个问题:

读取这种类型的数据很慢

答案:是的,它很慢,但是如果你将 sql 数据库中的图像保存为 VarBinary,它会很快。

我正在使用 OpenFileDialog1 带来图像或你想要的(Rar , Pdf .World ...)

  If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            Try
                T4.Text = OpenFileDialog1.FileName
                T5.Text = Path.GetExtension(OpenFileDialog1.FileName)
                T7.Text = Path.GetFileNameWithoutExtension(OpenFileDialog1.FileName)
            Catch ex As Exception
            End Try
        End If

这是我的代码,我用它来将数据保存在我的 Sql 数据库中:

 Dim SQLCON As New SqlConnection(MyDataBaseCon)
 Dim CMD As SqlCommand
 Try
        CMD = New SqlCommand("Insert Into TBLAtach (ID,AtachName,AtachMain,AtachFile,AtachNM,AtachDT,AtachAdres) Values (@ID,@AtachName,@AtachMain,@AtachFile,@AtachNM,@AtachDT,@AtachAdres)", SQLCON)
        SQLCON.Open()
        CMD.Parameters.Add(New SqlParameter("@ID", SqlDbType.Int)).Value = Val(T1.Text)
        CMD.Parameters.Add(New SqlParameter("@AtachName", SqlDbType.Int)).Value = Val(T2.Text)
        CMD.Parameters.Add(New SqlParameter("@AtachMain", SqlDbType.Int)).Value = Val(T3.Text)
        Dim FSTream As New FileStream(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
        Dim BNStream As New BinaryReader(FSTream)
        Dim FAttach() As Byte = BNStream.ReadBytes(BNStream.BaseStream.Length)
        CMD.Parameters.Add(New SqlParameter("@AtachFile", SqlDbType.VarBinary)).Value = FAttach
        CMD.Parameters.Add(New SqlParameter("@AtachNM", SqlDbType.NVarChar, 50)).Value = T5.Text
        CMD.Parameters.Add(New SqlParameter("@AtachDT", SqlDbType.NVarChar, 50)).Value = TD1.Text
        CMD.Parameters.Add(New SqlParameter("@AtachAdres", SqlDbType.NVarChar, 250)).Value = T7.Text
        CMD.ExecuteNonQuery()
        SQLCON.Close()
        FSTream.Close()
        BNStream.Close()
        MsgBox("Ok ", MsgBoxStyle.Information)
        SearchID()
        ClearTxT()
    Catch ex As Exception
        MsgBox(ex.Message)
        SQLCON.Close()
        WaitPic.Visible = False
    End Try

使用上面的代码,保存一个word文档但信息只是编码字符

答案:检索数据(图片、Pdf、RAR、...) 我正在使用此代码:

   Try
        ItDataset.Clear()
        Flt = "Select ID ,  AtachAdres + AtachNM AS 'Fname' , AtachFile from TBLAtach where ID = " & T1.Text & ""
        ItDataset = GeneralDataManager.InquireData(ItDataset, Flt, "TBLAtach")
        If Me.BindingContext(ItDataset, "TBLAtach").Count > 0 Then
            Dim FName As String = ItDataset.Tables("TBLAtach").Rows(0).Item("Fname")
            Dim FAttach() As Byte = CType(ItDataset.Tables("TBLAtach").Rows(0).Item("AtachFile"), Byte())
            Dim FStream As New FileStream(FName.ToString, FileMode.OpenOrCreate, FileAccess.Write)
            FStream.Write(FAttach, 0, (FAttach.Length))
            Process.Start(FName)
            FStream.Close()
        End If
        WaitPic.Visible = False
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

并更改您与数据库连接的连接

我希望这个答案对你有好处。 谢谢。

【讨论】:

感谢 Aladein,您在使用 Crystal 报表吗?原谅我的无知,但我不明白你的代码=(。我不确定你的代码将如何产生差异并显示信息而不是编码信息。也许我没有很好地解释自己。 不..我不使用水晶报表..这是 vb.net 代码。 这是我的最后一个项目。(存档项目) 感谢 Aladein 我在上面解释了一点 =)

以上是关于如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹的主要内容,如果未能解决你的问题,请参考以下文章

从 SQL Server 插入一些数据的表中读取数据的问题

如何在 R 中将图像上传到 SQL Server

AWS Glue - 从 sql server 表中读取并作为自定义 CSV 文件写入 S3

如何从 SQL Server 读取 MS Access 数据库以更新一个或多个表列中的数据?

从 SQL Server 表中读取 Json 值

从 Access 数据库到 SQL Server 的图像