Отправьте запрос Post с текущим листом Excel в виде данных из нескольких частей, используя vba - PullRequest
1 голос
/ 02 марта 2020

Я пытаюсь отправить текущий рабочий лист Excel на API, принимающий Content-type: "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: 438: объект не поддерживает это свойство или метод

Переменная «data» в теле формы вызывает ошибку. Я не уверен, что мне не хватает! И я получил Content-type в теле запроса от почтальона, который работает нормально! Я совсем новичок в 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}

Как это работает только с именем файла в теле запроса, а не с содержимым ??

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Наконец-то, все готово!

Как упомянуло @TimWilliams в комментариях, в основном мне пришлось: 1. сначала сохранить файл из Excel 2. прочитать его обратно в Excel как String 3. Преобразовать в байты а затем отправьте его по http

Также этот пост очень помог: google.com / search? q = vba + post + excel + file + site: stackoverflow.com

Кроме того, если бы был способ отправить файл ActiveWorkbook.sheet ("MY_SHEET") непосредственно в API, это было бы действительно хорошо. Будем продолжать исследовать!

Спасибо @TimWilliams!

0 голосов
/ 02 марта 2020

Мне кажется, проблема в том, что вы пытаетесь "преобразовать" переменные "данные" Worksheet в String в вашей preparePayload функции .

Я не уверен, что вам нужно «подготовиться» к API, который вы используете, если это имя самого рабочего листа, вы можете получить его с помощью метода .Name, если это что-то другое, вы необходимо убедиться, что он правильно преобразован в строку или что он может быть неявно преобразован.

...