上传二进制文件并将其保存为服务器中的Excel

时间:2017-02-21 21:13:38

标签: javascript php angularjs excel file-upload

我有一个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文件中。

我该怎么办?

编辑I: 我认为我做错了,因为我创建了文件,但是有奇怪的字符,只有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);

完美无缺!

2 个答案:

答案 0 :(得分:1)

没有必要将File对象转换为ArrayBuffer。您可POST File反对服务器,并在fopen()使用"php://input"file_get_contents()php,请参阅Trying to Pass ToDataURL with over 524288 bytes Using Input Type Text

答案 1 :(得分:0)

使用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会将标头设置为适当的值。