繁体   English   中英

将Excel文件存储在SQL Server中

[英]Store excel file in SQL Server

我正在为这种情况寻找一个好的解决方案:

  • 我有一个带有SQL Server 2008 R2后端的asp.net应用程序。
  • 我需要允许用户上传文件并保存以供以后检索。
  • 另外,我需要解析此文件以在数据库端进行查询。 所以我既需要来自此文件的数据作为数据表,又需要来自sql的数据以合并结果。

所以这就是我的想法:

  1. 将excel文件作为varbinary(max)存储在SQL Server中-这将允许以后通过.net检索文件非常容易。
  2. 解析:一种方法是由用户上传文件后,使用openxml或一些第三方库将其解析为数据表,然后将其传递给存储过程,该过程将返回结果集。

我不喜欢这种方法,因为这意味着我们必须两次将大量数据传递到数据库(第一次是在传递整个文件时,第二次是在传递数据集时。

关于如何更有效地执行此操作的任何建议? 是否可以使用以下方式从varbinary max中读取数据:

SELECT *
FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0', 
                    'Data Source=D:\TestJET.xls;
                    Extended Properties=''Excel 12.0;HDR=NO;IMEX=1;ImportMixedTypes=Text''')...[Sheet1$]

但没有实际创建文件?

还是可能不将整个文件传递给db,而是从datatable构造回excel文件?

还是varbinary(max)不是最佳解决方案,而是更好地使用XML之类的不同数据类型?

Excel文件非常简单。 一个没有宏或公式的样式表。 (尽管无法转换为CSV)文件大小为200-800kb。

您从数据库构造excel文件的想法很有趣-这表明获取上载的相同文件并不重要,仅包含相同信息的文件就不重要了。 那是对的吗?

如果是这样,我将在服务器上解析上传的文件(我喜欢ClosedXML for C#excel work),以查询友好的形式将相关数据存储在数据库中,然后将原始文件丢弃。 当用户要求退回文件时,为他们创建一个具有正确内容的新文件。

注意XML数据类型列-它们对您可以执行的操作有限制

您可能需要查看SQL 2008 r2的FILESTREAM功能,以将文件存储在服务器中。 这里是概述和不错的博客文章 我不确定您要使用的文件类型是什么,或者需要使用什么类型,但是您可以选择使用批量插入,或者您已经指出了OPENDATASOURCE或稍后执行过程,然后使用FILESTREAM中的ID加载数据以进行链接数据。

您可以使用FileUpload控件将文件上传到服务器,然后可以在需要时每次检索文件。

从那里,您可以使用OleDbConnection读取excel文件,将每个提取的记录添加到列表中以逐一进行迭代,然后将它们插入数据库中。

这是一个使用三个类的小示例:CConexion(处理OleDbConnection进程),ExcelParser(将获取的记录读取并插入到数据库中,以便您可以在需要时查询它们)和ExcelRecord(代表每个注册表中数据的容器)您的ExcelFile。

当您的计算机上装有MS Office Excel 2010时,将安装这些OleDb库。 我已经测试了代码并且运行良好。

该excel文件在示例中称为Hoja1.xlsx,并存储在TestApp根目录下名为Files的文件夹中,当您打开该文件时,会有三个记录,每个记录都有两个字段(A1,B1),(A2,B2) ,(A3,B3)在文件的第一张纸上也称为Hoja1.xlsx

    ''CConexion Class:

    Imports System.Data.SqlClient
    Imports System.Data.OleDb
    Imports System.Data

    Public Class CConexion

    #Region "Private Variables"

        Dim sOleDbConnectionString As String = String.Empty
        Dim conexionOleDb As New OleDbConnection()

    #End Region

    #Region "Con_Ole"

        Public Interface IConexionOleDb

            Property retConexionOleDb() As OleDbConnection
            Sub retOpenOleDb()
            Sub retCloseOleDb()

        End Interface

        Public Property retConexionOleDb() As OleDbConnection

            Get
                Return conexionOleDb
            End Get
            Set(ByVal value As OleDbConnection)

            End Set

        End Property

        Public Sub retOpenOleDb()

            If Not conexionOleDb.State = System.Data.ConnectionState.Open Then
                conexionOleDb.Open()
            End If

        End Sub

        Public Sub retCloseOleDb()

            If Not conexionOleDb.State = ConnectionState.Closed Then
                conexionOleDb.Close()
            End If

        End Sub

    #End Region

    #Region "Constructors"

        Public Sub New()

        End Sub

        Public Sub New(ByVal rutaOleDb As String)

            sOleDbConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" _
                                                        & "Data Source=" & rutaOleDb _
                                                        & ";" & "Extended Properties=Excel 12.0;"
            conexionOleDb.ConnectionString = sOleDbConnectionString

        End Sub

    #End Region

    End Class

    ''ExcelRecord Class:

    Public Class ExcelRecord

        Private _RId As Short = 0
        Public Property RId() As Short
            Get
                Return _RId
            End Get
            Set(ByVal value As Short)
                _RId = value
            End Set
        End Property

        Private _RText As String = String.Empty
        Public Property RText() As String
            Get
                Return _RText
            End Get
            Set(ByVal value As String)
                _RText = value
            End Set
        End Property

        Public Sub New()

        End Sub

        Public Sub New(ByVal Rid As Short, ByVal RText As String)
            Me.RId = Rid
            Me.RText = RText
        End Sub

    End Class

    ''ExcelParser Class:

    Imports System.Data.OleDb
    Imports System.Collections.Generic

    Public Class ExcelParser

        Private Function InsertRecords(ByVal objExcelRecords As List(Of ExcelRecord)) As Boolean
        ''Your code for insertion here
            Return True
        End Function

        Public Function ReadExcel(ByVal filePath As String) As Short

            Dim cn As New CConexion(filePath)
            Dim dr As OleDbDataReader
            Dim OperationState As Boolean = False
            Dim objExcelRecords As New List(Of ExcelRecord)

            Try

                Dim cmd As New OleDbCommand("Select * from [Hoja1$]", cn.retConexionOleDb)

                cn.retOpenOleDb()
                dr = cmd.ExecuteReader

                While dr.Read    

                    Dim objExcelRecord As New ExcelRecord(CShort(dr(0)), CStr(dr(1)))
                    objExcelRecords.Add(objExcelRecord)

                End While

                OperationState = InsertRecords(objExcelRecords)
                CType(dr, IDisposable).Dispose()

            Catch ex As Exception

            Finally

                cn.retCloseOleDb()
                cn.retConexionOleDb.Dispose()

            End Try

            Return OperationState

        End Function

    End Class


''Test Page ExcelReader.aspx.vb
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then

            Dim filePath As String = Server.MapPath("~\Files\Hoja1.xlsx")
            Dim objExcelParser As New ExcelParser()

            If objExcelParser.ReadExcel(filePath) Then
                Response.Write("Read!")
            Else
                Response.Write("No Read!")
            End If

        End If

    End Sub

让我知道这是否适合您。 希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM