2

Laravel 4で作成されたRESTful Webサービスにスプレッドシートを「アップロード」しようとしています。

同じ作業を行う Web フォームがありますが、ユーザーを Web アプリケーションに移動させてファイルを手動でアップロードする代わりに、ボタンをクリックするだけで (マクロを使用して) シートをアップロードできるようにする必要があります。を受け取ってInput::file('filename')ファイルを開いて読み取るメソッドがあります。VBA オブジェクトを使用してMicrosoft.XMLHTTP、要求を WS に送信しています。悲しいことに、どうやらファイルをアップロードできないようです。postメソッドでパス(絶対パス)を送信しているのですが、うまくいきません。

問題は、VBA コード内でこれを行うにはどうすればよいかということです。VBA コードを使用してサーバーにファイルをアップロードするにはどうすればよいですか? そして、可能であれば、それをlaravelアプリケーションと互換性を持たせるにはどうすればよいですか?

編集

@Andreycoの質問に適切に答えるために、私はこの編集を行っています。

これは、VBA Debug Tool でダンプを返すときに受け取るものです。Input::all()

Array
(
    [spreedsheet] => C:\Users\Android\Desktop\tarifa.xls
)

…が、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
    )
)

... Laravelの構造などのせいです。それが役に立つことを願っています。

4

3 に答える 3

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

新しいモジュールを作成します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

フォームを作成します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

次に、ワークシートにボタンを追加し ([開発] タブがない場合は、[オプション] -> [リボンのカスタマイズ] -> [開発] チェックボックスを有効にします)、マクロを割り当て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"]);
?>

ソース:

于 2015-06-29T09:31:54.990 に答える
0

フォローしているIT ブログでそれを理解したところ、 「手袋のように」役に立ちました。2 つの単純な VBA 関数/メソッドだけで、うまく機能しました。ファイルと URL を渡すだけで完了です。

助けてくれてありがとう@Andreyco!;)

于 2013-07-18T19:04:30.637 に答える