【问题标题】:Upload binary file and save it like an Excel in server上传二进制文件并将其像 Excel 一样保存在服务器中
【发布时间】:2017-07-11 17:04:57
【问题描述】:

我有一个 JavaScript 函数,它读取一个 excel 文件并在 document.getElementById("content").value 中返回一个对象 ArrayBuffer:

  <script type = "text/javascript">
        function readFile(files){
            console.log("DEntro de readFile");
            var reader = new FileReader();
            reader.readAsArrayBuffer(files[0]);
            reader.onload = function(event){
                var arrayBuffer = event.target.result;
                array = new Uint8Array(arrayBuffer);
                binaryString = String.fromCharCode.apply(null, array);
                document.getElementById("fileContent").value = event.target.result;     
            }
        }
  </script>

所以,我想知道,如何将此对象 ArrayBuffer 发送到服务器,并在服务器中将此 ArrayBuffer 保存在生成​​原始 Excel 的 Excel 文件中。

我能做什么?

编辑我: 我认为我做错了什么,因为我创建了文件,但是有奇怪的字符并且只有 31 个字节。

JavaScript:

    function readFile(files){
        var reader = new FileReader();
        reader.readAsArrayBuffer(files[0]);
        reader.onload = function(event){
            document.getElementById("fileContent").value = event.target.result;     
        }

    }

Angular JS 使用此函数,我以 JSON 格式将数据发送到服务器:

 self.uploadFile = function(){
     var data = {
        file    :   document.getElementById("fileContent").value,
     };
     publicDataServices.sendData("http://gnsys.local/publico/test/up", data).then(function(response){
         switch(parseInt(response.result)){
             case 0:
                 console.log("OK!!!");
                 break;
             case 3:    //Error de Sistemas
                 console.log("testControllers.js::uploadFile: Error de sistemas");
                 break;                              
         }
     });
 }

PHP:

    $params = json_decode(file_get_contents('php://input'),true);
    $property = new PropertyReader();
    $fileRoute = $property->getProperty("scripts.ruta.querys");
    $fileName = $fileRoute . "prueba.xls";

    $input = fopen('php://input', 'rb');
    $file = fopen($fileName, 'wb');

    stream_copy_to_stream($input, $file);
    fclose($input);
    fclose($file);

编辑 II(有效!):

Angular JS:

 self.uploadFile = function(){
     publicDataServices.sendData("http://gnsys.local/publico/test/up", document.getElementById("file").files[0]).then(function(response){
         switch(parseInt(response.result)){
             case 0:
                 console.log("OK!!!");
                 break;
             case 3:    //Error de Sistemas
                 console.log("testControllers.js::uploadFile: Error de sistemas");
                 break;                              
         }
     });
 }

PHP:

    $property = new PropertyReader();
    $fileRoute = $property->getProperty("scripts.ruta.querys");
    $fileName = $fileRoute . "prueba.xls";

    $input = fopen('php://input', 'rb');
    $file = fopen($fileName, 'wb');

file_get_contents and file_put_contents
        stream_copy_to_stream($input, $file);
        fclose($input);
        fclose($file);

我只是知道如何获取原始文件名。

编辑 III(发送文件名): Angular js:

 self.uploadFile = function(){ 
        var promise = $q.defer();
        var headers = {
            "file-name" :   document.getElementById("file").files[0].name
        }
        $http.post("http://gnsys.local/publico/test/up", document.getElementById("file").files[0], {headers:headers})
        .success(function(response, status, headers, config){
            promise.resolve(response);
            console.log("resultado: " + response.result);
        })
        .error(function(data){
            //Error de sistemas
            console.log("Error en sendData: " + data)
        })

        return promise.promise;      
 }

PHP:

    $property = new PropertyReader();
    $fileRoute = $property->getProperty("scripts.ruta.querys");
    $fileName = $fileRoute . "prueba.xls";
    //With this foreach we get all the headers so I can detect which i the right header to get the file name
    foreach (getallheaders() as $name => $value) {
        $log->writeLog(get_class($this) . "::" . __FUNCTION__ . ": name: " . $name . " value: " . $value);
    }

    $input = fopen('php://input', 'rb');
    $file = fopen($fileName, 'wb');

    stream_copy_to_stream($input, $file);
    fclose($input);
    fclose($file);

效果很好!

【问题讨论】:

  • 如果需要将ArrayBuffer 发送到服务器,调用String.fromCharCode() 的目的是什么?见stackoverflow.com/questions/37491759/…
  • 也许不需要 String.fromCharCode()。我会尝试删除该代码。谢谢!!!
  • .files[0] 元素的.files[0] 属性发送到服务器。 .value 是一个字符串,C:\\fakepath。你为什么打电话给json_decodephppublicDataServices.sendData("http://gnsys.local/publico/test/up", document.getElementById("fileContent").files[0])php 删除第一行。
  • FileReader 不是必需的。 input.onchange = function() { publicDataServices.sendData("http://gnsys.local/publico/test/up", document.getElementById("fileContent").files[0]) }。虽然没有尝试过angugularjs,但不确定库如何处理将Blob 发送到服务器。您也可以使用XMLHttpRequest()fetch()File 对象发送到服务器。 request.send(document.getElementById("fileContent").files[0]),或fetch("path/to/server", {method:"POST", body:document.getElementById("fileContent").files[0]})

标签: javascript php angularjs excel file-upload


【解决方案1】:

使用 AngularJS $http 服务发送文件 blob 时,将内容类型标头设置为原始值 undefined 很重要。

var config = { headers: { 'Content-Type': undefined } };

$http.post(url, file[0], config).then(function(response) {
    var data = response.data;
    var status = response.status;
    console.log("status: ", status);
});

通常 $http 服务将内容类型标头设置为application/json。通过将内容类型标头设置为undefinedXHR Send Method 会将标头设置为适当的值。

【讨论】:

    【解决方案2】:

    不必将File 对象转换为ArrayBuffer。你可以POSTFile对象到服务器并使用fopen()"php://input"file_get_contents()php,见Trying to Pass ToDataURL with over 524288 bytes Using Input Type Text

    【讨论】:

    • 我需要读取一个excel文件并发送到服务器,但是我不能使用POST,我必须发送一个流。
    • “但是我不能使用 POST,我必须发送流” “发送流”是什么意思?文件如何发送到服务器?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    相关资源
    最近更新 更多