|  Error visualizacion archivo docx recuperado SQL Server, metodo BinaryWrite  
  Hola:Tengo una aplicación web (ASP) en la que los usuarios pueden adjuntar y visualizar todo tipo de documentos (pdf, tiff, jpeg, doc, xls…). Estos documentos se almacenan en una tabla de SQL Server 2005, utilizando un campo de tipo “image”.
 Para almacenar los documentos, utilizo el archivo Loader.asp, que circula por internet:
 
 <%
 ' -- Loader.asp --
 ' -- version 1.5
 ' -- last updated 6/13/2002
 
 Class Loader
 Private dict
 
 Private Sub Class_Initialize
 Set dict = Server.CreateObject("Scripting.Dictionary")
 End Sub
 
 Private Sub Class_Terminate
 If IsObject(intDict) Then
 intDict.RemoveAll
 Set intDict = Nothing
 End If
 If IsObject(dict) Then
 dict.RemoveAll
 Set dict = Nothing
 End If
 End Sub
 
 Public Property Get Count
 Count = dict.Count
 End Property
 
 Public Sub Initialize
 If Request.TotalBytes > 0 Then
 Dim binData
 binData = Request.BinaryRead(Request.TotalBytes)
 getData binData
 End If
 End Sub
 
 Public Function getFileData(name)
 If dict.Exists(name) Then
 getFileData = dict(name).Item("Value")
 Else
 getFileData = ""
 End If
 End Function
 
 Public Function getValue(name)
 Dim gv
 If dict.Exists(name) Then
 gv = CStr(dict(name).Item("Value"))
 
 gv = Left(gv,Len(gv)-2)
 getValue = gv
 Else
 getValue = ""
 End If
 End Function
 
 Public Function saveToFile(name, path)
 If dict.Exists(name) Then
 Dim temp
 temp = dict(name).Item("Value")
 Dim fso
 Set fso = Server.CreateObject("Scripting.FileSystemObject")
 Dim file
 Set file = fso.CreateTextFile(path)
 For tPoint = 1 to LenB(temp)
 file.Write Chr(AscB(MidB(temp,tPoint,1)))
 Next
 file.Close
 saveToFile = True
 Else
 saveToFile = False
 End If
 End Function
 
 Public Function getFileName(name)
 If dict.Exists(name) Then
 Dim temp, tempPos
 temp = dict(name).Item("FileName")
 tempPos = 1 + InStrRev(temp, "\")
 getFileName = Mid(temp, tempPos)
 Else
 getFileName = ""
 End If
 End Function
 
 Public Function getFilePath(name)
 If dict.Exists(name) Then
 Dim temp, tempPos
 temp = dict(name).Item("FileName")
 tempPos = InStrRev(temp, "\")
 getFilePath = Mid(temp, 1, tempPos)
 Else
 getFilePath = ""
 End If
 End Function
 
 Public Function getFilePathComplete(name)
 If dict.Exists(name) Then
 getFilePathComplete = dict(name).Item("FileName")
 Else
 getFilePathComplete = ""
 End If
 End Function
 
 Public Function getFileSize(name)
 If dict.Exists(name) Then
 getFileSize = LenB(dict(name).Item("Value"))
 Else
 getFileSize = 0
 End If
 End Function
 
 Public Function getFileSizeTranslated(name)
 If dict.Exists(name) Then
 temp = 1 + LenB(dict(name).Item("Value"))
 If Len(temp) <= 3 Then
 getFileSizeTranslated = temp & " bytes"
 ElseIf Len(temp) > 6 Then
 temp = FormatNumber(((temp / 1024) / 1024), 2)
 getFileSizeTranslated = temp & " megabytes"
 Else
 temp = FormatNumber((temp / 1024), 2)
 getFileSizeTranslated = temp & " kilobytes"
 End If
 Else
 getFileSizeTranslated = ""
 End If
 End Function
 
 Public Function getContentType(name)
 If dict.Exists(name) Then
 getContentType = dict(name).Item("ContentType")
 Else
 getContentType = ""
 End If
 End Function
 
 Private Sub getData(rawData)
 Dim separator
 separator = MidB(rawData, 1, InstrB(1, rawData, ChrB(13)) - 1)
 
 Dim lenSeparator
 lenSeparator = LenB(separator)
 
 Dim currentPos
 currentPos = 1
 Dim inStrByte
 inStrByte = 1
 Dim value, mValue
 Dim tempValue
 tempValue = ""
 
 While inStrByte > 0
 inStrByte = InStrB(currentPos, rawData, separator)
 mValue = inStrByte - currentPos
 
 If mValue > 1 Then
 value = MidB(rawData, currentPos, mValue)
 
 Dim begPos, endPos, midValue, nValue
 Dim intDict
 Set intDict = Server.CreateObject("Scripting.Dictionary")
 
 begPos = 1 + InStrB(1, value, ChrB(34))
 endPos = InStrB(begPos + 1, value, ChrB(34))
 nValue = endPos
 
 Dim nameN
 nameN = MidB(value, begPos, endPos - begPos)
 
 Dim nameValue, isValid
 isValid = True
 
 If InStrB(1, value, stringToByte("Content-Type")) > 1 Then
 
 begPos = 1 + InStrB(endPos + 1, value, ChrB(34))
 endPos = InStrB(begPos + 1, value, ChrB(34))
 
 If endPos = 0 Then
 endPos = begPos + 1
 isValid = False
 End If
 
 midValue = MidB(value, begPos, endPos - begPos)
 intDict.Add "FileName", trim(byteToString(midValue))
 
 begPos = 14 + InStrB(endPos + 1, value, stringToByte("Content-Type:"))
 endPos = InStrB(begPos, value, ChrB(13))
 
 midValue = MidB(value, begPos, endPos - begPos)
 intDict.Add "ContentType", trim(byteToString(midValue))
 
 begPos = endPos + 4
 endPos = LenB(value)
 
 nameValue = MidB(value, begPos, endPos - begPos)
 Else
 nameValue = trim(byteToString(MidB(value, nValue + 5)))
 End If
 
 If isValid = true Then
 intDict.Add "Value", nameValue
 intDict.Add "Name", nameN
 
 dict.Add byteToString(nameN), intDict
 End If
 End If
 
 currentPos = lenSeparator + inStrByte
 Wend
 End Sub
 
 End Class
 
 Private Function stringToByte(toConv)
 Dim tempChar
 For i = 1 to Len(toConv)
 tempChar = Mid(toConv, i, 1)
 stringToByte = stringToByte & chrB(AscB(tempChar))
 Next
 End Function
 
 Private Function byteToString(toConv)
 For i = 1 to LenB(toConv)
 byteToString = byteToString & chr(AscB(MidB(toConv,i,1)))
 Next
 End Function
 %>
 
 Este archivo está incluido en la página de acción (<!--#include file="../../includes/Loader.asp"-->), en la que hago lo siguiente:
 
 Dim load
 Set load = new Loader
 load.initialize
 
 Obtengo la información que necesito para hacer la insert:
 
 fileData = load.getFileData("file")
 Nombre = LCase(load.getFileName("file"))
 Tamano = load.getFileSize("file")
 contentType = load.getContentType("file")
 Descripcion = load.getValue("descripcion")
 TipoDocumento = load.getValue("TipoDocumento")
 
 Defino las variables de conexión, e inserto el registro:
 
 rsInsert.Open NombreTabla, objetoConexion, 2, 2
 rsInsert.AddNew
 rsInsert("TipoDocumento") = TipoDocumento
 rsInsert("Nombre") = Nombre
 rsInsert("Tamaño") = Tamano
 rsInsert("Descripcion") = Descripcion
 rsInsert("Fichero").AppendChunk fileData
 rsInsert("TipoDatos") = contentType
 rsInsert.Update
 rsInsert.Close
 
 Para visualizar los documentos, tengo un asp que se carga en un iframe, recogiendo la información de SQL y haciendo solamente lo siguiente:
 
 Response.addHeader "Content-Disposition","inline;filename=" & NombreFichero
 Response.ContentType = TipoDatos
 Response.BinaryWrite Fichero
 Response.End
 
 Esto ha estado funcionando durante varios años perfectamente para todo tipo de documentos.
 Haciendo pruebas por tema de migración a Office 2010, estoy teniendo problemas con los documentos Word (docx) y Excel (xlsx). Los archivos se guardan aparentemente sin problemas en la base de datos (TipoDatos = “application/vnd.openxmlformats-officedocument.wordprocessingml.document” y “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”), pero a la hora de visualizar los documentos tengo problemas.
 
 Al intentar abrir el archivo docx, me sale una ventana para guardar el archivo (en lugar de mostrarlo directamente en el explorador como hace con el resto de documentos). Una vez descargado, al abrirlo desde el explorador de Windows, dice lo siguiente: “El archivo no se puede abrir porque hay problemas con el contenido. Detalles:  El archivo está dañado y no se puede abrir”. Me ofrece la opción de recuperar el contenido y al final consigo ver el contenido del documento.
 Con el archivo xlsx, también me pasa algo parecido, pero en lugar de darme la opción de guardarlo, me da la opción de recuperarlo, lo consigue y me lo muestra en la ventana correcta (internet explorer).
 
 También he probado a meter los tipos MIME en el IIS, pero sigue sin funcionar.
 
 El resto de documentos siguen funcionado correctamente.
 
 Las pruebas las he realizado en Internet Explorer 8.
 
 He leído algo sobre algún byte extra que puede estar guardándose en SQL, pero no se me ocurre una solución.
 
 Perdón por la chapa, pero no me he querido dejar ningún detalle.
 
 Espero que me podáis ayudar, porque empiezo a estar un poco desesperado.
 
 Muchas gracias
 
   Última edición por zigor; 03/05/2011 a las 09:24
     |