如何从工作表(通过VBA宏)将文件上传到laravel应用程序?

Den*_*aga 2 rest excel-vba web laravel laravel-4

我正在尝试将一个spreedsheet“上传自身”到Laravel 4中制作的RESTful Web服务。

我有一个执行相同工作的Web表单,但是我需要使表单能够通过单击按钮(使用宏)自行上传,而不是使用户转到Web应用程序并手动上传文件。我有一个接收的方法,Input::file('filename')然后打开文件进行读取和填充。我正在使用Microsoft.XMLHTTPVBA对象将请求发送到WS。遗憾的是,我似乎无法上传damm文件!我在post方法中发送路径(绝对路径),但不起作用。

问题是:如何在VBA代码中执行此操作?如何通过VBA代码将文件上传到服务器?并且,如果可能的话,如何使它与laravel应用程序兼容?

编辑

为了正确回答@Andreyco的问题,我正在进行此编辑。

这就是我返回的转储时,在VBA调试工具中收到的内容。 Input::all()

Array
(
    [spreedsheet] => C:\Users\Android\Desktop\tarifa.xls
)
Run Code Online (Sandbox Code Playgroud)

...但是,当我从Web表单收到响应时,看起来像这样。

Array
(
    [_token] => rvtkLep6rwvkvvXc3u0WoO6nyldylp9xI36n6gb2
    [spreedsheet] => Symfony\Component\HttpFoundation\File\UploadedFile Object
    (
        [test:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 
        [originalName:Symfony\Component\HttpFoundation\File\UploadedFile:private] => tarifa.xls
        [mimeType:Symfony\Component\HttpFoundation\File\UploadedFile:private] => application/vnd.ms-excel
        [size:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 43520
        [error:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 0
        [pathName:SplFileInfo:private] => /tmp/phpRsX5bf
        [fileName:SplFileInfo:private] => phpRsX5bf
    )
)
Run Code Online (Sandbox Code Playgroud)

...由于Laravel的结构和材料。希望它会有用。

Jac*_*ler 5

这里是一个完整的工作示例。如果不需要“请稍候”对话框,只需使用第一个代码段并将其删除UploadThisFileMain。还要注意最后的服务器PHP测试脚本。

Sub UploadThisFileMain()
   If ActiveWorkbook.Saved = False Then
       MsgBox "This workbook contains unsaved changes. Please save first."
       Exit Sub
   End If
   Dim ret
   ret = StartProcessing("File uploading, Please Wait...", "UploadThisFile")
   If (ret = True) Then
       MsgBox "Upload successful!"
    Else
       MsgBox "Upload failed: " & ret
   End If
End Sub

Private Function UploadThisFile()
    Dim bound As String
    bound = "A0AD2346-9849-4EF0-9A93-ACFE17910734"

    Dim url  As String
    url = "https://<YourServer>/index.php?id={" & bound & "}"

    Dim path As String
    path = ThisWorkbook.path & "\" & ThisWorkbook.Name

    sMultipart = pvGetFileAsMultipart(path, bound)

    On Error Resume Next

    Dim r
    r = pvPostMultipart(url, sMultipart, bound)

    If Err.Number <> 0 Then
      UploadThisFile = Err.Description
      Err.Clear
    Else
      UploadThisFile = True
    End If
End Function

'sends multipart/form-data To the URL using WinHttprequest/XMLHTTP
'FormData - binary (VT_UI1 | VT_ARRAY) multipart form data
Private Function pvPostMultipart(url, FormData, Boundary)
  Dim http 'As New MSXML2.XMLHTTP

  'Create XMLHTTP/ServerXMLHTTP/WinHttprequest object
  'You can use any of these three objects.
  'Set http = CreateObject("WinHttp.WinHttprequest.5")
  'Set http = CreateObject("MSXML2.XMLHTTP")
  Set http = CreateObject("MSXML2.ServerXMLHTTP")

  'Open URL As POST request
  http.Open "POST", url, False

  'Set Content-Type header
  http.setRequestHeader "Content-Type", "multipart/form-data; boundary=" + Boundary

  'Send the form data To URL As POST binary request
  http.send FormData

  'Get a result of the script which has received upload
  pvPostMultipart = http.responseText
End Function

Private Function pvGetFileAsMultipart(sFileName As String, Boundary As String) As Byte()
    Dim nFile           As Integer
    Dim sPostData       As String
    '--- read file
    nFile = FreeFile
    Open sFileName For Binary Access Read As nFile
    If LOF(nFile) > 0 Then
        ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
        Get nFile, , baBuffer
        sPostData = StrConv(baBuffer, vbUnicode)
    End If
    Close nFile
    '--- prepare body
    sPostData = "--" & Boundary & vbCrLf & _
        "Content-Disposition: form-data; name=""uploadfile""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
        "Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
        sPostData & vbCrLf & _
        "--" & Boundary & "--"
    '--- post
    pvGetFileAsMultipart = pvToByteArray(sPostData)
End Function

Private Function pvToByteArray(sText As String) As Byte()
    pvToByteArray = StrConv(sText, vbFromUnicode)
End Function
Run Code Online (Sandbox Code Playgroud)

创建一个新模块Processing_Code

Public Processing_Message As String
Public Macro_to_Process As String
Public Return_Value As String

Function StartProcessing(msg As String, code As String)

   Processing_Message = msg    'Set the message that is displayed
                               'in the dialog box

   Macro_to_Process = code     'Set the macro that is run after the
                               'dialog box is active

   Processing_Dialog.Show      'Show the Dialog box

   StartProcessing = Return_Value
End Function
Run Code Online (Sandbox Code Playgroud)

创建一个表单Processing_Dialog。设置StartUpPosition2 - CenterScreen。添加代码:

Private Sub UserForm_Initialize()

   lblMessage.Caption = Processing_Message  'Change the Label
                                            'Caption

End Sub

Private Sub UserForm_Activate()

   Me.Repaint                                        'Refresh the UserForm
   Return_Value = Application.Run(Macro_to_Process)  'Run the macro
   Unload Me                                         'Unload the UserForm

End Sub
Run Code Online (Sandbox Code Playgroud)

现在将一个按钮添加到您的工作表中(如果没有“ Developer”选项卡,请转到“选项”->“自定义功能区”->启用复选框“ Developer”)并分配宏UploadThisFileMain

对于服务器部分,请使用以下PHP测试脚本:

<?php
foreach (getallheaders() as $name => $value) {
    echo "$name: $value\n";
}

echo "POST:";
print_r($_POST);
echo "GET:";
print_r($_GET);
echo "FILES:";
print_r($_FILES);

$entityBody = file_get_contents('php://input');
        echo "Body:$entityBody";

exit;
$base_dir = dirname( __FILE__ ) . '/upload/';
if(!is_dir($base_dir))
    mkdir($base_dir, 0777);
move_uploaded_file($_FILES["uploadfile"]["tmp_name"], $base_dir . '/' . $_FILES["uploadfile"]["name"]);
?>
Run Code Online (Sandbox Code Playgroud)

资料来源: