求助:LotusScript通过multipart/form-data上传PDF文件损坏问题
LotusScript上传PDF文件损坏问题的解决方法
问题背景
需通过multipart/form-data方式上传PDF文件,但现有代码上传后API收到的文件损坏,需修正文件读取逻辑或更换可靠的上传方式。
现有上传代码
filePath = louidoc.FieldGetText("PdfFile") ' Generate a unique boundary for the multipart form data boundary = "---------------------------" & Format(Now, "yyyyMMddHHmmss") ' Construct the multipart/form-data request body formData = "--" & boundary & Chr(13) & Chr(10) & "Content-Disposition: form-data; name=""id_requisito""" & Chr(13) & Chr(10) & Chr(13) & Chr(10) & idRequisito & Chr(13) & Chr(10) _ & "--" & boundary & Chr(13) & Chr(10) _ & "Content-Disposition: form-data; name=""file""; filename=""" & filePath & """" & Chr(13) & Chr(10) _ & "Content-Type: application/pdf" & Chr(13) & Chr(10) & Chr(13) & Chr(10) _ & FileToStringv2(filePath) & Chr(13) & Chr(10) _ & "--" & boundary & "--" & Chr(13) & Chr(10) ' Set the Content-Type header for the request contentType = "multipart/form-data; boundary=" & boundary ' Create an instance of MSXML2.ServerXMLHTTP Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP") ' Open a POST request to the specified URL xmlHttp.open "POST", url, False ' Set the Content-Type header xmlHttp.setRequestHeader "Content-Type", contentType ' Send the multipart/form-data request body xmlHttp.send formData
现有文件读取函数及问题
原FileToString函数存在读取错误,尝试修改后仍导致文件损坏:
Function FileToString(filePath As String) As String Dim fileNum As Integer Dim fileContent As String Dim fileSize As Long ' Attempt to open the file On Error Resume Next fileNum = Freefile() Open filePath For Binary As fileNum If Err <> 0 Then FileToString = "" ' Return empty string if unable to open the file Exit Function End If On Error Goto 0 ' Determine the size of the file fileSize = Filelen(filePath) ' Read the entire content of the file into a string If fileSize > 0 Then fileContent = Space$(fileSize)+1 ' Create a string buffer of the file size stringlen = Len(fileContent) Get #fileNum, , fileContent Else fileContent = "" ' File is empty or size is zero End If ' Close the file Close fileNum ' Return the file content as a string FileToString = fileContent End Function ' 尝试的修改代码 ' Use LOF to find the file length, and Input$ to read the entire file into the string veriable izFile. fileContent$ = Input$(Lof(fileNum%), fileNum%) Close fileNum fileNum% = Freefile() Open filePath For Input As fileNum% vFileContent = Input(Lof(fileNum%), fileNum%) Close fileNum
解决方案
方法1:使用ADODB.Stream处理二进制内容(推荐)
PDF属于二进制文件,直接转字符串会因编码问题丢失字节,使用ADODB.Stream可直接处理二进制流,彻底避免文件损坏:
Sub UploadPDFWithStream(filePath As String, idRequisito As String, url As String) Dim boundary As String Dim stream As Object Dim xmlHttp As Object ' 生成唯一分隔符 boundary = "---------------------------" & Format(Now, "yyyyMMddHHmmss") ' 创建ADODB.Stream主对象(二进制模式) Set stream = CreateObject("ADODB.Stream") stream.Type = 1 ' adTypeBinary stream.Open ' 写入文本参数部分(转二进制避免编码干扰) Dim textPart As String textPart = "--" & boundary & vbCrLf & _ "Content-Disposition: form-data; name=""id_requisito""" & vbCrLf & vbCrLf & _ idRequisito & vbCrLf & _ "--" & boundary & vbCrLf & _ "Content-Disposition: form-data; name=""file""; filename=""" & Dir(filePath) & """" & vbCrLf & _ "Content-Type: application/pdf" & vbCrLf & vbCrLf Dim textStream As Object Set textStream = CreateObject("ADODB.Stream") textStream.Type = 2 ' adTypeText textStream.Charset = "UTF-8" textStream.Open textStream.WriteText textPart textStream.Position = 0 textStream.Type = 1 textStream.CopyTo stream textStream.Close Set textStream = Nothing ' 写入PDF文件二进制内容 Dim fileStream As Object Set fileStream = CreateObject("ADODB.Stream") fileStream.Type = 1 fileStream.Open fileStream.LoadFromFile filePath fileStream.CopyTo stream fileStream.Close Set fileStream = Nothing ' 写入结束分隔符 Dim endPart As String endPart = vbCrLf & "--" & boundary & "--" & vbCrLf Set textStream = CreateObject("ADODB.Stream") textStream.Type = 2 textStream.Charset = "UTF-8" textStream.Open textStream.WriteText endPart textStream.Position = 0 textStream.Type = 1 textStream.CopyTo stream textStream.Close Set textStream = Nothing ' 发送请求 Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP") xmlHttp.Open "POST", url, False xmlHttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary stream.Position = 0 xmlHttp.send stream ' 清理资源 stream.Close Set stream = Nothing Set xmlHttp = Nothing End Sub
方法2:修复二进制文件读取函数(仅兼容小文件)
若必须使用字符串拼接,需确保二进制内容正确读取,避免编码干扰:
Function ReadBinaryFile(filePath As String) As String Dim fileNum As Integer Dim fileContent As String Dim fileSize As Long On Error Resume Next fileNum = FreeFile() Open filePath For Binary Access Read As #fileNum If Err <> 0 Then ReadBinaryFile = "" Exit Function End If On Error GoTo 0 fileSize = LOF(fileNum) If fileSize > 0 Then ' 正确分配缓冲区并读取二进制内容 fileContent = Space$(fileSize) Get #fileNum, , fileContent Else fileContent = "" End If Close #fileNum ReadBinaryFile = fileContent End Function
使用此函数替换原FileToStringv2,注意:该方法处理含Null字节或大文件时仍可能出错,优先推荐方法1。
内容的提问来源于stack exchange,提问作者Lea Giardili
相关产品推荐
相关产品推荐

