You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:25:55