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?
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
Reset to default 6OK 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)