1

I'm trying to create a CSV file that will be saved with UTF-16LE encoding on the server and then pass the result to the client. This is what I do, in Coffeescript:

Meteor.methods {
    iconv: (data, from="UTF-8", to="UTF-16LE") ->
        Iconv = Meteor.require('iconv').Iconv
        iconv = new Iconv(from, to)
        res = iconv.convert(data) 
        res
}

Now if I write the file from the server with the line

fs.writeFileSync('/tmp/test.csv', res)

the file is correctly generated. However, I would like to avoid creating a file on the server and save it directly on the client (using the filesaver library). The sample client code looks like this:

exportToCsv = (data="tête", filename) ->
    callback = (err, res) ->
        blob = new Blob([res], {type:'text/csv;charset=UTF-16LE'})
        saveAs(blob, filename)
    Meteor.call('iconv', data, callback)

As you can see, the data I'm testing with is a simple string with a special character (the 'ê'). My problem is that I cannot pass the nodejs buffer to the client. It is automatically serialised into:

Object {0: 116, 1: 0, 2: 234, 3: 0, 4: 116, 5: 0, 6: 101, 7: 0}

instead of the buffer output that I get on the server:

<Buffer 74 00 ea 00 74 00 65 00>

The problem is not so much the conversion from hexadecimal to decimal, I know I can convert back to hexadecimal using something Number(116).toString(16). But how do I write this data as binary in the blob?

1 Answer 1

6

OK so in the end it turned out that I was almost there. The only thing I needed to do for the data to be saved correctly in the Blob was to get the data as an array of numbers from the server (through the toJSON() method) and then to create a Uint8Array on the client before saving it to a file blob through the blob.

So on the server:

Meteor.methods {
    iconv: (data, from="UTF-8", to="UTF-16LE") ->
        Iconv = Meteor.require('iconv').Iconv
        iconv = new Iconv(from, to)
        res = iconv.convert(data) 
        res
}

And on the client:

exportToCsv = (data="tête", filename) ->
    callback = (err, res) ->
        byteArray = new Uint8Array(res)
        blob = new Blob([byteArray], {type:'text/csv'})
        saveAs(blob, filename)
    Meteor.call('iconv', data, callback)
Sign up to request clarification or add additional context in comments.

2 Comments

You've saved my day, I will love you till the end.
You also saved my long day ! I'll loved you too !

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.