none
GUARDAR ARCHIVO WORD EN SQL Y MOSTRARLO EN WINFORMS RRS feed

  • Pregunta

  • MI PROBLEMA:

    REALIZO LA SUIGUIENTE RUTINA PARA GUARDAR UN ARCHIVO WORD EN SQL:


    DECLARO LO SIGUIENTE:

    Dim fs As System.IO.FileStream

    Dim bw As System.IO.BinaryWriter


    Inserto un componente (DLL) WinWordControl para visualizar el documento Word antes de guardar

    insertamos el objeto OpenFileDialog1

    En el evento Load del formulario inserto el siguiente código:  (Para filtrar tipo de documento)

    OpenFileDialog1.Filter = "Documentos Digitales (*.doc)|*.doc"
    OpenFileDialog1.FileName = ""
    OpenFileDialog1.InitialDirectory = "C:\"


    Resumen: tenemos 1 formulario, 1 componente WinWordControl, 1 Objeto OpenFileDialog1 y 2 botones.

    1 botón para buscar el archivo Word para visualizarlo en el WinWordControl


    1 botón para guardar el archivo en SQL


    EL COMPONENTE: WinWordControl en mi proyecto se llama visual_Word


    Código Para buscar el archivo Word:


        Private Sub btn_doc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_doc.Click


            visual_word.Visible = True

            Try

                Dim filNm As String

                If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
                    filNm = OpenFileDialog1.FileName
                    '
                    txt_ruta_word.Text = filNm.ToString

                    visual_word.LoadDocument(OpenFileDialog1.FileName)
                Else
                    'nada
                End If


            Catch ex As Exception
                MsgBox("Error; " & Err.Description, MsgBoxStyle.Exclamation + MsgBoxStyle.OkOnly, "Errores")
            End Try


        End Sub


    PARA QUE SE PUEDA COMPRENDER MI CÓDIGO, TENGO UN MÓDULO DENOMINADO CONEXIONES ASÍ:


    Imports System.Data.Sql
    Imports System.Data.SqlClient
    Imports System.Configuration

    Module Conexiones

    Friend conexion As New SqlConnection(ConfigurationManager.ConnectionStrings("StrCnxBD").ToString)

        ' Normal
        Friend SC As New SqlCommand
        Friend DA As New SqlDataAdapter
        Friend DS As New DataSet()
        Friend DT As New DataTable

    End Module


    SE ENTIENDE QUE CON EL CÓDIGO ANTERIOR YA ESTAMOS VISUALIZANDO EL ARCHIVO WORD. AHORA LO GUARDAMOS EN SQL:


    Botón Guardar:

            'obtener la extención del archivo
                Dim aText() As String, sExt As String
                aText = Split(OpenFileDialog1.FileName, ".")
                sExt = aText(UBound(aText))


        Dim Myfile As System.IO.FileStream
                    Myfile = System.IO.File.OpenRead(Me.txt_ruta_word.Text)
                    Dim Arr(Myfile.Length) As Byte 'Declaramos el array para manejar los bytes almacenar


                    DS.Tables.Clear()
                    DT.Rows.Clear()
                    DT.Columns.Clear()
                    DS.Clear()
                    SC.Parameters.Clear()


                    Myfile.Read(Arr, 0, Myfile.Length)
                    SC.Connection = conexion

                    SC.CommandType = CommandType.Text
                    SC.CommandText = ("insert into archivo(nombre, documento, extencion) VALUES (@nombre, @documento, @extencion)")

                    SC.Parameters.Add("@nombre", SqlDbType.varchar, 50).Value = (nombre que queramos darle)


                    SC.Parameters.Add("@documento", SqlDbType.VarBinary).Value = Arr
                    SC.Parameters.Add("@extencion", SqlDbType.NVarChar, 20).Value = sExt


                    DA.SelectCommand = SC
                    DA.Fill(DT)
                    DS.Tables.Add(DT)


    CON ESTO YA GUARDAMOS EL ARCHIVO WORD EN SQL.

    AHORA EL GRAN PROBLEMA:


    VISUALIZAR EL ARCHIVO WORD EN EL FORMULARIO EN EL COMPONENTE WinWordControl


    Botón Nº 3 : ver archivo Word


    EL PROCEDIMIENTO ALMACENADO ES UN SELECT DONDE WHERE ES EL ID DEL DOCUMENTO GUARDADO.

    Código:


        Try

                DS.Tables.Clear()
                DT.Rows.Clear()
                DT.Columns.Clear()
                DS.Clear()
                SC.Parameters.Clear()

                SC.Connection = conexion
                SC.CommandType = CommandType.StoredProcedure
                SC.CommandText = "sp_ver_word"

                SC.Parameters.Add("@VALOR", SqlDbType.Int).Value = 1  (Fuerzo el ID del documento guardado)

                DA.SelectCommand = SC
                DA.Fill(DT)
                DS.Tables.Add(DT)

                conexion.Open()
                SC.ExecuteNonQuery()
                conexion.Close()

                If DS.Tables(DT.TableName).Rows.Count > 0 Then

                    Dim nom = DS.Tables(DT.TableName).Rows(0).Item("NOMBRE_DOC")
                    Dim ext = DS.Tables(DT.TableName).Rows(0).Item("extencion")

                    Dim myread As SqlClient.SqlDataReader

                    Dim bits() As Byte

                    conexion.Open()
                    myread = SC.ExecuteReader
                    myread.Read()

                    '3 indica el numero de columa del blog en el data reader
                    ' Aqui declaramos nuetros array de datos al tamaño que tiene en la base de datos
                    Dim filedata(myread.GetBytes(2, 0, Nothing, 0, Integer.MaxValue) - 1) As Byte
                    myread.GetBytes(2, 0, filedata, 0, filedata.Length)
                    Dim myext As String
                    Select Case myread(3)

                        Case "PDF"
                            myext3 = "pdf"
                        Case "WORD 2000-2003"
                            myext3 = "doc"
                        Case "WORD 2007-"
                            myext3 = "docx"
                        Case "JPG"
                            myext3 = "jpg"
                        Case "AVI"
                            myext3 = "avi"
                        Case Else
                            myext3 = ext
                    End Select

                    AQUI TENGO 2 OPCIONES: CREO EL ARCHIVO Y LO TRAIGO A UNA RUTA O LO CREO TEMPORALMENTE

                    ' ALTERNATIVA 1 Aqui creo el nombre del archivo a recuperar con su extension correcta
                    Dim ExtensionNombre3 As String = nom3 & "." & ext


                    'ALTERNATIVA 2 GENERO EL WORD TEMPORAL
                    '        Dim ExtensionNombre3 = System.IO.Path.GetTempFileName().Replace(".tmp", ".doc")
                    ' System.IO.File.ReadAllBytes()


                    ' Aqui creamos el archivo
                    Dim fs As System.IO.FileStream = New System.IO.FileStream(ExtensionNombre, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write)
                    bw = New System.IO.BinaryWriter(fs)
                    bw.Write(filedata)
                    bw.Flush()
                    bw.Close()
                    fs.Close()

                    myread.Close()

    NO SÉ COMO MOSTRAR EL ARCHIVO WORD
    AQUI SE CAE:
                         visual_word.LoadDocument(ExtensionNombre3)


                Else
                    'nada
                End If

            Catch ex As Exception
                MsgBox("Error; " & Err.Description, MsgBoxStyle.Exclamation + MsgBoxStyle.OkOnly, "Errores")
            End Try

    La idea original es de: LUIS MENDOZA FLAMENCO

    Modificado por mi: Héctor Estay Romero

    Si pueden me escriben a:hestay@tinfo.cl

    • Cambiado Enrique M. Montejo domingo, 25 de diciembre de 2016 9:00 Pregunta relacionada con Windows Forms.
    viernes, 23 de diciembre de 2016 14:07

Todas las respuestas

  • Hola a todo aquel que me pueda ayudar.

    Avancé en el código con resultados positivos pero me falta para llegar a lo que necesito.

    Estuve leyendo un código de ejemplo de un tema relacionado a mi problema de Don Don Enrique M. Montejo.

    Agregue lo siguiente al código:

        Private Shared Sub WriteBinaryFile(ByVal filename As String, ByVal data As Byte())

            ' Comprobación de los valores de los parámetros.
            '
            If (String.IsNullOrEmpty(filename)) Then _
                Throw New ArgumentException("No se ha especificado el archivo de destino.", "fileName")

            If (data Is Nothing) Then _
                Throw New ArgumentException("Los datos no son válidos para crear un archivo.", "data")

            ' Crear el archivo. Se producirá una excepción si ya existe
            ' un archivo con el mismo nombre.
            Using fs As New IO.FileStream(filename, IO.FileMode.CreateNew, IO.FileAccess.Write)

                ' Crea el escritor para la secuencia.
                Dim bw As New IO.BinaryWriter(fs)

                ' Escribir los datos en la secuencia.
                bw.Write(data)

            End Using

        End Sub

                    WriteBinaryFile("C:\word\" & ExtensionNombre, filedata)
                    visor_word.LoadDocument("C:\word\" & ExtensionNombre)

    CON ESTO, consigo que me cree el archivo Word y que lo muestre en el control WinWordControl.

    Lo que no entiendo es lo siguiente:

    Cuando selecciono el archivo word con extención .docx WinWordControl me permite  visualizar el dicumento y lo puedo guardar en Sql sin problemas, pero cuando quiero visualizarlo desde la base de datos me da el siguiente error:

    "Error; El comando no está disponible porque no existe ningún documento abierto"

    Por otra parte me crea el documento en la ruta especificada pero al abrirlo directamente dice que esta dañado y bla bla bla y lo abre después desde la aplicación word.

    Pero si el documento y todo el proceso de guardado y visualización lo realizo con un archivo de extinción .doc no da ningún problema. me parece raro que WinWordControl si permita visualizar el archivo .docx antes de guardarlo.

    Cualquier ayuda o sugerencia bienvenida sea......

    Saludos. 

    lunes, 26 de diciembre de 2016 12:30
  • Estimados todos jajajaj al parecer soy yo y nadie más porque nadie ve ni comenta nada jejeje

    Como sea, mi conclusión es que archivos de extención docx, xlsx y todo lo que tenga X, no se puede guardar como datos binarios ya que docx esta basado en XAML, XML WPF, etc...

    Si Uds. le cambian la exención DOCX de un archivo Word por ZIP y ven su estructura verán que se compone de XAML, XML, etc.. osea no es 100% binario como DOC. Si lo guardan con el código expuesto lo verán como archivo dañado con error. ahora si lo abren dieractemnte en Word lo pueden recuperar pero con varios pasos lo cual no es apropiado para un desarrollo de software ya que la idea es que se vea, guarde, edite y visualice sin errores. 

    Si a alguien le sirve, con este código puede guardar archivos doc y verlos desde windows forms

    Si alguien necesita le puedo orientar de como hacer esto como así también con los archivos PDF. Yo logré insertar PDF en SQL desde Windows Forms como asi también visualizarlos.

    Cualquier idea sobre como almacenar DOCX en SQL, bienvenida sea.

    Seguiré insistiendo para ver que puedo hacer con AXML.

    Saludos...

    martes, 27 de diciembre de 2016 18:58
  • Hola a todos...... osea a mí jejeje

    Bueno, para el que pueda leer este hilo, les cuento que logré guardar archivos DOCX en Sql Server desde Windows Forms.

    Lo logré.........

    Si alguien quiere saber como lo hice, al menos pídalo por este medio y sin ningún problema compartiré el conocimiento.

    Con este laboratorio pude desde Windows Forms: 

    * Buscar, Ver, Guardar, Editar PDF en Sql Server

    * Buscar, Ver, Guardar, editar Archivos DOC en Sql Server

    * Buscar, Ver, Guardar, Editar Archivos DOCX en Sql Server

    hestay@tinfo.cl

    Héctor Estay desde Chile

    SALUDOS.......

    miércoles, 28 de diciembre de 2016 15:13
  • Héctor,

    Me encontré con la misma problemática planteada por el área de desarrollo.

    Agradeceré me puedas compartir tus hallazgos.


    desde ya gracias.

    martes, 29 de mayo de 2018 19:28
  • Que tal Héctor, buen día. Podrías apoyarme en compartir el proyecto que tienes para leer y guardar el contenido de un archivo word a SQL, lo quiero aplicar para un proyecto en VB.NET 2012. Saludos y gracias por tu atención. Mi correo es olopez_vo@hotmail.com
    sábado, 15 de diciembre de 2018 19:12