none
Descargar un documento Excel o Words de Bd SQL en un campo varbinary RRS feed

  • Pregunta

  • Hola,

    Después de subir un archivo Excel o Word 2016 se consigue descargar, guardar y abrir pero primero aparece el mensaje

    en Word:

    Lo sentimos No se puede abrir el archivo ??.docx porque existe un problema con el contenido, Aceptas y dice haber encontrado un documento con contenido ilegible, ¿Desea recuperar el contenido del documento? si hace si, lo abre y los puedes ver.

    En Excel ocurre lo mismo con mensajes de corrección parecidos.

    El código usado para descargar es el siguiente:

                Dim aBytDocumento() As Byte = Nothing
                Dim oFileStream As FileStream
                Dim lsQuery As String = "Select ImFilestream From ImAlmacenImagenes Where ImIdImagen =" & ImIdImagen
                Using loConexion As New SqlConnection(Conectividad.GlbModSesionServices.cadenaConexion)
                    Using loComando As New SqlCommand(lsQuery, loConexion)
                        loConexion.Open()
                        Using drDocumentos As SqlDataReader = loComando.ExecuteReader(CommandBehavior.SingleRow)
                            If drDocumentos.Read() Then
                                aBytDocumento = CType(drDocumentos("ImFileStream"), Byte())
                            End If
                        End Using
                    End Using
                    oFileStream = New FileStream("C:\tmp\PEPE.docx", FileMode.CreateNew, FileAccess.Write)
                    oFileStream.Write(aBytDocumento, 0, aBytDocumento.Length)
                    oFileStream.Close()
                End Using
                Dim loPSI As New ProcessStartInfo
                Dim loProceso As New Process
                loPSI.FileName = "C:\tmp\PEPE.docx"
                loProceso = Process.Start(loPSI)

    domingo, 19 de junio de 2016 11:35

Respuestas

  • "Jparera" escribió:

    > Este es el código que lo sube a la BD, por si hay algo incorrecto:
    >
    >  Dim rs As New ADODB.Recordset
    >
    >  Dim sqlTxt As String
    >  sqlTxt = "SELECT * " & _
    >           "FROM " & nombreTabla & " " & _
    >           "WHERE " & NombreCampoLoc & "= '" & datoLoc & "'"
    > With rs
    >     .Open(sqlTxt, conexionOLEDB, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockPessimistic, 1)
    >     '** Damos de alta nuevo registro
    >     If .EOF = True Or AddnewSiempre = True Then
    >         .AddNew()
    >         .Fields("ImFileStream").Value = ArrDeBytes
    >         .Update()
    >         .Close()

    Hola:

    Ese es el código que supuestamente utilizas para abrir un objeto Recordset de la biblioteca de ADO clásica, y actualizar el valor del campo "ImFileStream" con el valor de la matriz (array) llamada 'ArrDeBytes'.

    ¿Podemos conocer el motivo de tener que utilizar la biblioteca de ADO clásica en un proyecto de Visual Basic .NET para conectarte a una base de datos de SQL Server?

    Mira a ver si para guardar ese array en la base de datos te sirve el ejemplo que encontrarás en el siguiente artículo:

    Cómo guardar archivos en una base de datos

    Obviamente, en lugar de ejecutar una consulta SQL de selección, tendrás que ejecutar una consulta T-SQL de actualización (UPDATE) para actualizar un registro concreto:

        UPDATE NombreTabla
        SET NombreCampo = @nuevoValor
        WHERE NombreCampoLoc = @valorNombreCampoLoc

    Por lo que tendrás que modificar la consulta INSERT INTO que aparece en el ejemplo por la consulta UPDATE anterior, una vez que la adaptes a tus necesidades, añadiendo asimismo los dos parámetros de entrada que aparecen en la misma.

    Y para crear un documento de Word, Excel, *.pdf, etc., con los datos previamente guardados en la base de datos, échale un vistazo al ejemplo que aparece en éste otro artículo:

    Cómo leer los archivos contenidos en una base de datos

    Adapta los ejemplos a tus necesidades.

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.





    lunes, 27 de junio de 2016 19:04
    Moderador

Todas las respuestas

  • Si unzipeas el pepe.docx (puedes renombrarlo as pepe.zip), ¿el zip se descomprime sin problemas? Tal vez el problema no está en el contenido sino en su empaquetado.

    Tal vez lo estés arruinando con la rutina de subida... 

    domingo, 19 de junio de 2016 14:04
  • El código que usas para extraer el archivo desde la base de datos parece ser correcto. ¿Puede ser que el documento se encuentre ya corrompido dentro del registro de la base de datos, es decir, que haya quedado mal grabado? ¿Has verificado por algún otro método que el contenido que hay en el registro sea correcto?
    domingo, 19 de junio de 2016 17:29
  • Hola,

    Este es el código que lo sube a la BD, por si hay algo incorrecto:

    JP Cargamos el fichero a leer
    DocStream = File.OpenRead(RutaMasNombre)
    Lo pasamos a una variable filestream en una funcion externa y lo pasamos a la BD
     
     Dim ArrDeBytes(ArchivoFileStream.Length) As Byte
            'JP Pasamos de Filestream al array de bytes
            ArchivoFileStream.Read(ArrDeBytes, 0, ArchivoFileStream.Length)
     Dim rs As New ADODB.Recordset
            Dim sqlTxt As String
            sqlTxt = "SELECT * " & _
                     "FROM " & nombreTabla & " " & _
                      "WHERE " & NombreCampoLoc & "= '" & datoLoc & "'"
            With rs
                .Open(sqlTxt, conexionOLEDB, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockPessimistic, 1)
                '** Damos de alta nuevo registro
                If .EOF = True Or AddnewSiempre = True Then
                    .AddNew()
                    '.Fields("ImIdImagen").Value=0
                     .Fields("ImFileStream").Value = ArrDeBytes
       .Update()
                  .Close()
         end if
     end with

    lunes, 27 de junio de 2016 14:48
  • "Jparera" escribió:

    > Este es el código que lo sube a la BD, por si hay algo incorrecto:
    >
    >  Dim rs As New ADODB.Recordset
    >
    >  Dim sqlTxt As String
    >  sqlTxt = "SELECT * " & _
    >           "FROM " & nombreTabla & " " & _
    >           "WHERE " & NombreCampoLoc & "= '" & datoLoc & "'"
    > With rs
    >     .Open(sqlTxt, conexionOLEDB, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockPessimistic, 1)
    >     '** Damos de alta nuevo registro
    >     If .EOF = True Or AddnewSiempre = True Then
    >         .AddNew()
    >         .Fields("ImFileStream").Value = ArrDeBytes
    >         .Update()
    >         .Close()

    Hola:

    Ese es el código que supuestamente utilizas para abrir un objeto Recordset de la biblioteca de ADO clásica, y actualizar el valor del campo "ImFileStream" con el valor de la matriz (array) llamada 'ArrDeBytes'.

    ¿Podemos conocer el motivo de tener que utilizar la biblioteca de ADO clásica en un proyecto de Visual Basic .NET para conectarte a una base de datos de SQL Server?

    Mira a ver si para guardar ese array en la base de datos te sirve el ejemplo que encontrarás en el siguiente artículo:

    Cómo guardar archivos en una base de datos

    Obviamente, en lugar de ejecutar una consulta SQL de selección, tendrás que ejecutar una consulta T-SQL de actualización (UPDATE) para actualizar un registro concreto:

        UPDATE NombreTabla
        SET NombreCampo = @nuevoValor
        WHERE NombreCampoLoc = @valorNombreCampoLoc

    Por lo que tendrás que modificar la consulta INSERT INTO que aparece en el ejemplo por la consulta UPDATE anterior, una vez que la adaptes a tus necesidades, añadiendo asimismo los dos parámetros de entrada que aparecen en la misma.

    Y para crear un documento de Word, Excel, *.pdf, etc., con los datos previamente guardados en la base de datos, échale un vistazo al ejemplo que aparece en éste otro artículo:

    Cómo leer los archivos contenidos en una base de datos

    Adapta los ejemplos a tus necesidades.

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.





    lunes, 27 de junio de 2016 19:04
    Moderador
  • Hola Enrique,

    El motivo de usar la biblioteca de ADO es porque esto forma parte de un proyecto mayor que la usa en toda la aplicación. La idea era mantener la homogeneidad pero parece ser que no encuentro la solución desde ADO.

    He probado el código escrito en Cómo guardar archivos en una base de datos y guarda bien y después con el código de lectura que fallaba funciona correcto.

    Tendré que utilizar este sistema, aunque primero cambiare la sentencia a INSERT.

    Gracias.

    Joan Parera

    martes, 28 de junio de 2016 15:27