使用 vba 发送 Post 请求,将当前 excel sheet 作为多部分表单数据
Send a Post request with the current excel sheet as multi-part form data using vba
我正在尝试将当前工作 excel sheet 发送到 api 接受内容类型:"multipart-form"。
我需要帮助来形成 vba 中的请求。
以下是我的做法:
Sub sendInternalDataToAPI(myCSVFileName As String)
Dim data As Worksheet
Dim boundary As String
Dim filename As String
boundary = "--------------------------784780577729000449617522"
filename = "data"
Set data = ActiveWorkbook.Sheets("DATA")
'Set payload = preparePayload(data)
Url = "http://localhost:8080/load"
Set objHTTP = CreateObject("Microsoft.XMLHTTP")
With objHTTP
.Open "POST", Url, False
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.setRequestHeader "Content-type", "multipart/form-data;boundary=" & boundary
.send (preparePayload(data, boundary, myCSVFileName))
strResponseStatus = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print strResponseStatus
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub
Function preparePayload(data As Worksheet, boundary As String, filename As String) As String
Debug.Print boundary & vbCrLf & _
"Content-Disposition: form-data; name=""data""; filename=""" & filename & """" & vbCrLf & _
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" & vbCrLf & _
data & vbCrLf & _
boundary & "--"
preparePayload = boundary & vbCrLf & _
"Content-Disposition: form-data; name=""data""; filename=""" & filename & """" & vbCrLf & _
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" & vbCrLf & _
data & vbCrLf & _
boundary & "--"
End Function
执行时出现以下错误:
VBA Error: 438: Object doesn't support this property or method
表单正文中的变量 "data" 导致错误。我不确定我错过了什么!
而且,我从邮递员那里得到了请求正文中的内容类型,它执行得很好!
我是 vba 的新手,非常感谢任何帮助。
谢谢!
更新:
来自邮递员控制台的邮递员请求是:
Request ---
POST <url>/load HTTP/1.1
User-Agent: PostmanRuntime/7.22.0
Accept: */*
Cache-Control: no-cache
Postman-Token: d3a4355f-548a-4b10-b8b7-53c62772cc4a
Host: localhost:8080
Content-Type: multipart/form-data; boundary=--------------------------360126624207643168890089
Accept-Encoding: gzip, deflate, br
Content-Length: 352982
Connection: keep-alive
----------------------------360126624207643168890089
Content-Disposition: form-data; name="data"; filename="test-excel.xlsx"
<test-excel.xlsx>
----------------------------360126624207643168890089--
Response---
HTTP/1.1 200 OK
Date: Tue, 03 Mar 2020 13:41:17 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Transfer-Encoding: chunked
response Body fromt the server--
{"data":true}
如何仅使用请求正文中的文件名而不使用内容?
我认为问题在于您正在尝试将 "convert" Worksheet 变量 "data" 转换为 String 在您的 preparePayload 函数 中。
我不确定您使用的 API "prepare" 需要什么,如果它是工作表本身的名称,您可以使用 .Name 方法获取它,如果是其他东西,您需要确保将其正确转换为字符串,或者确保它可以隐式转换。
终于搞定了!
正如@TimWilliams 在评论中提到的,基本上我必须:
1.先从excel保存文件
2. 将其作为字符串读回 excel
3.转换成Bytes然后通过http
发送
这个 post 也帮了大忙:google.com/search?q=vba+post+excel+file+site:whosebug.com
此外,如果有一种方法可以将 ActiveWorkbook.sheet("MY_SHEET") 直接发送到 api,那就太好了。
会继续探索!
谢谢@TimWilliams!
我正在尝试将当前工作 excel sheet 发送到 api 接受内容类型:"multipart-form"。 我需要帮助来形成 vba 中的请求。 以下是我的做法:
Sub sendInternalDataToAPI(myCSVFileName As String)
Dim data As Worksheet
Dim boundary As String
Dim filename As String
boundary = "--------------------------784780577729000449617522"
filename = "data"
Set data = ActiveWorkbook.Sheets("DATA")
'Set payload = preparePayload(data)
Url = "http://localhost:8080/load"
Set objHTTP = CreateObject("Microsoft.XMLHTTP")
With objHTTP
.Open "POST", Url, False
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.setRequestHeader "Content-type", "multipart/form-data;boundary=" & boundary
.send (preparePayload(data, boundary, myCSVFileName))
strResponseStatus = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print strResponseStatus
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub
Function preparePayload(data As Worksheet, boundary As String, filename As String) As String
Debug.Print boundary & vbCrLf & _
"Content-Disposition: form-data; name=""data""; filename=""" & filename & """" & vbCrLf & _
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" & vbCrLf & _
data & vbCrLf & _
boundary & "--"
preparePayload = boundary & vbCrLf & _
"Content-Disposition: form-data; name=""data""; filename=""" & filename & """" & vbCrLf & _
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" & vbCrLf & _
data & vbCrLf & _
boundary & "--"
End Function
执行时出现以下错误:
VBA Error: 438: Object doesn't support this property or method
表单正文中的变量 "data" 导致错误。我不确定我错过了什么! 而且,我从邮递员那里得到了请求正文中的内容类型,它执行得很好! 我是 vba 的新手,非常感谢任何帮助。
谢谢!
更新: 来自邮递员控制台的邮递员请求是:
Request ---
POST <url>/load HTTP/1.1
User-Agent: PostmanRuntime/7.22.0
Accept: */*
Cache-Control: no-cache
Postman-Token: d3a4355f-548a-4b10-b8b7-53c62772cc4a
Host: localhost:8080
Content-Type: multipart/form-data; boundary=--------------------------360126624207643168890089
Accept-Encoding: gzip, deflate, br
Content-Length: 352982
Connection: keep-alive
----------------------------360126624207643168890089
Content-Disposition: form-data; name="data"; filename="test-excel.xlsx"
<test-excel.xlsx>
----------------------------360126624207643168890089--
Response---
HTTP/1.1 200 OK
Date: Tue, 03 Mar 2020 13:41:17 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Transfer-Encoding: chunked
response Body fromt the server--
{"data":true}
如何仅使用请求正文中的文件名而不使用内容?
我认为问题在于您正在尝试将 "convert" Worksheet 变量 "data" 转换为 String 在您的 preparePayload 函数 中。
我不确定您使用的 API "prepare" 需要什么,如果它是工作表本身的名称,您可以使用 .Name 方法获取它,如果是其他东西,您需要确保将其正确转换为字符串,或者确保它可以隐式转换。
终于搞定了!
正如@TimWilliams 在评论中提到的,基本上我必须: 1.先从excel保存文件 2. 将其作为字符串读回 excel 3.转换成Bytes然后通过http
发送这个 post 也帮了大忙:google.com/search?q=vba+post+excel+file+site:whosebug.com
此外,如果有一种方法可以将 ActiveWorkbook.sheet("MY_SHEET") 直接发送到 api,那就太好了。 会继续探索!
谢谢@TimWilliams!