2

I have a JavaScript function which reads an excel file and return me an object ArrayBuffer in document.getElementById("content").value:

  <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>

So, I would like to know, how can I send this object ArrayBuffer to the server and in the server save this ArrayBuffer in an excel file generating the original Excel.

What can I do?

EDIT I: I think I'm doing something wrong, because I create the file, but with strange characters and with only 31 bytes.

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 With this function I send data to the server in a 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);

Edit II (it works!):

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);

I just only to know how to get the original file name.

Edit III (sending file name): 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);

It works perfectly!

8
  • 1
    What is purpose of String.fromCharCode() call if requirement is to send ArrayBuffer to server? See stackoverflow.com/questions/37491759/… Commented Feb 21, 2017 at 21:22
  • Maybe is not necessary String.fromCharCode(). I'l try to delete that code. Thanks!!! Commented Feb 21, 2017 at 21:35
  • 1
    Send .files[0] property of <input type="file"> element to server. .value is a string, C:\\fakepath. Why do you call json_decode at php? publicDataServices.sendData("http://gnsys.local/publico/test/up", document.getElementById("fileContent").files[0]), at php remove first line. Commented Feb 21, 2017 at 21:50
  • 1
    FileReader is not necessary. input.onchange = function() { publicDataServices.sendData("http://gnsys.local/publico/test/up", document.getElementById("fileContent").files[0]) }. Though have not tried angugularjs, not sure how the library handles sending Blob to server. You could alternatively use XMLHttpRequest() or fetch() to send File object to server. request.send(document.getElementById("fileContent").files[0]), or fetch("path/to/server", {method:"POST", body:document.getElementById("fileContent").files[0]}) Commented Feb 21, 2017 at 21:59
  • 1
    stackoverflow.com/questions/541430/…, stackoverflow.com/questions/2902621/… Commented Feb 21, 2017 at 22:08

2 Answers 2

1

It is not necessary to convert File object to ArrayBuffer. You can POST File object to server and utilize fopen(), "php://input", file_get_contents() at php, see Trying to Pass ToDataURL with over 524288 bytes Using Input Type Text

Sign up to request clarification or add additional context in comments.

2 Comments

I need to read an excel file and send to the server, but I can't use POST, I have to send an stream.
"but I can't use POST, I have to send an stream" What do you mean by "send an stream"? How is file sent to server?
0

When sending a file blob using the AngularJS $http service, it is important to set the content type header to the primitive value 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);
});

Normally the $http service sets the content type header to application/json. By setting the content type header to undefined, the XHR Send Method will set the header to the appropriate value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.