VB .NET - Armazenando documentos PDF em um banco de dados


Este artigo  mostra uma forma de armazenar e recuperar documentos PDF em um banco de dados SQL Server 2008 Express.

Os recursos usados serão:

Ambos são gratuitos e podem ser baixados no site da Microsoft.

Definindo o banco de dados e a tabela

O banco de dados usado neste projeto foi criado no projeto : VB .NET - Armazenando documentos em um banco de dados

Ele usa o Microsoft SQL Server 2012 Express LocalDB chamado Gedoc.mdf.

Vamos criar uma tabela chamada DocumentosPDF contendo a seguinte estrutura neste banco de dados:

Para visualizar o clique no menu VIEW clique em Other Windows -> DataBase Explorer para abrir a DataBase Explorer exibindo as conexões existentes com as fontes de dados:

O Microsoft SQL Server 2012 Express LocalDB é um modo de execução do SQL Server Express destinado a desenvolvedores de programas.

A instalação do LocalDB copia um conjunto mínimo de arquivos necessários para iniciar o mecanismo de Banco de Dados do SQL Server.

Quando o LocalDB é instalado, os desenvolvedores iniciam uma conexão usando uma cadeia de conexão especial.

Na conexão, a infraestrutura necessária do SQL Server é criada e iniciada automaticamente, permitindo que o aplicativo use o banco de dados sem tarefas de configuração complexas ou demoradas.

O Developer Tools pode fornecer aos desenvolvedores um mecanismo de Banco de Dados do SQL Server que permite que eles gravem  e testem o código Transact-SQL sem precisar gerenciar uma instância de servidor inteira do SQL Server. Uma instância do SQL Server Express LocalDB é gerenciada com o utilitário SqlLocalDB.exe.

O SQL Server Express LocalDB deve ser usado em lugar do recurso de instância de usuário do SQL Server Express, que ficou obsoleto.

Expanda os objetos da conexão e clique com o botão direito do mouse sobre Tables;

No menu suspenso clique em Add New Table;

Na janela do descritor SQL defina a estrutura da tabela com os seguintes campos:

Se você clicar sobre a conexão com o banco de dados Gedoc poderá ver na janela de propriedades a string de conexão definida:

Criando o projeto no Visual Basic 2010

Abra o Visual Basic 2010 Express e no menu File clique em New Project e selecione a linguagem Visual Basic e o template Windows Forms Application informando o nome SalvandoRecuperandoPDF;

Será criada uma solução contendo o projeto Windows Forms com um formulário form1.vb e arquivo de configuração App.Config.

Vamos incluir no formulário form1.vb os seguintes controles:

Conforme o leiaute abaixo:

Salvando documentos PDF

Neste formulário defina as declarações dos namespaces que iremos usar :

Imports System.Data.SqlClient
Imports System.IO
Imports System.Security
imports System.Diagnostics

No botão btnlocalizar vamos incluir o código que permite ao usuário selecionar um documento para ser salvo no banco de dados.

Para isso vamos abrir uma janela Open File Dialog a partir da qual o usuário irá selecionar o arquivo:

Private Sub btnLocalizar_Click(sender As Object, e As EventArgs) Handles btnLocalizar.Click
        'define as propriedades do controle 
        'OpenFileDialog
        Me.ofd1.Multiselect = False
        Me.ofd1.Title = "Selecionar Documento"
        ofd1.InitialDirectory = "C:\dados\"
        'aplica um filtro 
        ofd1.Filter = "Arquivos (*.PDF;*.AVI;*.MP3;*.BMP;*.JPG;*.GIF,*.PNG,*.TIFF)|*.PDF;*.AVI;*.MP3;*.BMP;*.JPG;*.GIF;*.PNG;*.TIFF|" & "Todos (*.*)|*.*"
        ofd1.CheckFileExists = True
        ofd1.CheckPathExists = True
        ofd1.FilterIndex = 2
        ofd1.RestoreDirectory = True
        Dim dr As DialogResult = Me.ofd1.ShowDialog()

        If dr = System.Windows.Forms.DialogResult.OK Then
            If String.IsNullOrEmpty(ofd1.FileName) Then
                Return
            End If
            Try
                txtArquivoPDF.Text += ofd1.FileName
                'define os dados do documento
                btnSalvar.Enabled = True

            Catch ex As SecurityException
                ' O usuário  não possui permissão para ler arquivos
                MessageBox.Show((("Erro de segurança Contate o administrador de segurança da rede." &
                                                                vbLf & vbLf & "Mensagem : ") + ex.Message &
                                                                vbLf & vbLf & "Detalhes (enviar ao suporte):" & vbLf & vbLf) + ex.StackTrace)
            Catch ex As Exception
                ' Não pode carregar a imagem (problemas de permissão)
                MessageBox.Show(("Não é possível acessar o arquivo : " &
                                                                ofd1.FileName & ". Você pode não ter permissão para ler o arquivo , ou " _
                                                                 & " ele pode estar corrompido." & vbLf & vbLf & "Erro reportado : ") + ex.Message)
            End Try
        End If
    End Sub

Após selecionar o arquivo e obter os dados documento o usuário deverá clicar no botão Salvar para armazenar o documento no banco de dados. O código deste botão é visto abaixo:

Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click

        Using conn As New SqlConnection("Data Source=(localdb)\v11.0;Initial Catalog=Gedoc;Integrated Security=True")
            conn.Open()
            Using cmd As New SqlCommand("Insert Into DocumentosPDF (arquivoPDF) Values (@PDF)", conn)
                cmd.Parameters.Add(New SqlParameter("@PDF", SqlDbType.VarBinary)).Value = File.ReadAllBytes(txtArquivoPDF.Text)
                cmd.ExecuteNonQuery()
            End Using
        End Using

End Sub

Recuperando documentos PDF

No evento Click do botão de comando Recuperar Arquivo PDF do formulário temos o código que acessa a tabela DocumentosPDF e exibe o documento PDF:

Private Sub btnRecupera_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRecupera.Click
        Dim caminhoArquivoPDF As String
        Dim buffer As Byte()

        'If txtArquivoPDF.Text = String.Empty Then
        '    Return
        'End If

        Using conn As New SqlConnection("Data Source=(localdb)\v11.0;Initial Catalog=Gedoc;Integrated Security=True")
            'Dim sql As String = "Select arquivoPDF From DocumentosPDF where arquivoPDF = '" & txtArquivoPDF.Text & "'"
            conn.Open()
            Using cmd As New SqlCommand("Select Top 1 arquivoPDF From DocumentosPDF", conn)
                buffer = cmd.ExecuteScalar()
            End Using
        End Using

        caminhoArquivoPDF = System.IO.Path.GetTempFileName()
        File.Move(caminhoArquivoPDF, Path.ChangeExtension(caminhoArquivoPDF, ".pdf"))
        caminhoArquivoPDF = System.IO.Path.ChangeExtension(caminhoArquivoPDF, ".pdf")

        File.WriteAllBytes(caminhoArquivoPDF, buffer)
        Dim act As Action(Of String) = New Action(Of String)(AddressOf AbrirArquivoPDF)
        act.BeginInvoke(caminhoArquivoPDF, Nothing, Nothing)

    End Sub

O código acima recupera sempre o primeiro documento da tabela, se desejar selecionar um documento informando pelo usuário monte uma cláusula SQL (eu deixei um exemplo comentado) usando um critério pelo nome do arquivo.

A rotina AbrirArquivoPDF que é chamada no código acima tem o seguinte código:

Private Shared Sub AbrirArquivoPDF(ByVal CaminhoArquivoPDF)
        Using p As New Diagnostics.Process
            p.StartInfo = New ProcessStartInfo(CaminhoArquivoPDF)
            p.Start()
            p.WaitForExit()
            Try
               File.Delete(CaminhoArquivoPDF)
            Catch
            End Try
        End Using
    End Sub

Executando o projeto vemos na figura abaixo a recuperação e exibição de um arquivo :

O objetivo básico do artigo foi cumprido : mostrei como podemos armazenar e recuperar documentos PDF em um banco de dados.

A forma de implementação usada não esta aderente às boas práticas e precisa ser melhorada.

Temos que separar responsabilidades, evitar código duplicado, facilitar a manutenção, etc.

Pegue o projeto completo aqui: SalvandoRecuperandoPDF.zip

1Pe 3:12 Porque os olhos do Senhor estão sobre os justos, e os seus ouvidos atento à sua súplica; mas o rosto do Senhor é contra os que fazem o mal.

1Pe 3:13 Ora, quem é o que vos fará mal, se fordes zelosos do bem?

1Pe 3:14 Mas também, se padecerdes por amor da justiça, bem-aventurados sereis; e não temais as suas ameaças, nem vos turbeis;

1Pe 3:15 antes santificai em vossos corações a Cristo como Senhor; e estai sempre preparados para responder com mansidão e temor a todo aquele que vos pedir a razão da esperança que há em vós;

1Pe 3:16 tendo uma boa consciência, para que, naquilo em que falam mal de vós, fiquem confundidos os que vituperam o vosso bom procedimento em Cristo.

Referências:


José Carlos Macoratti