将一个 byte[] 转换成 JavaScript Blob,使用 elemental2。

huangapple go评论88阅读模式
英文:

Convert a byte[] into a JavaScript Blob using elemental2

问题

我正在进行一个Domino-REST服务器调用来创建一个PDF。服务器创建了PDF并将其作为byte[]发送给客户端。现在我想在不打开另一个浏览器窗口的情况下将这个byte[]下载到客户端计算机上。

我找到了这个问题:File download a byte array as a file in javascript / Extjs,其中描述了如何做到这一点的方法。

现在,我面临的问题是,我必须使用elemntal2将我的byte[]转换为Blob。

任何帮助都将不胜感激。谢谢!

英文:

I am doing a Domino-REST server call to create a PDF. The server creates the PDF and send the PDF as byte[] to the client. Now I want to download the byte[] to the client computer without opening another browser window.

I'll found this question: File download a byte array as a file in javascript / Extjs which describes the way, how to do that.

Now, I am facing the problem, that I have to convert my byte[] to a Blob using elemntal2.

Any help is appreciated. Thanks

答案1

得分: 3

First, let's take a quick look at the MDN docs for Blob's constructor arguments:

Parameters

array - An iterable object such as an Array, having ArrayBuffers, TypedArrays, DataViews, Blobs, strings, or a mix of any of such elements, that will be put inside the Blob. Note that strings here are encoded as UTF-8, unlike the usual JavaScript UTF-16 strings.
options (Optional) - An object which may specify any of the following properties:

  • type Optional - The MIME type of the data that will be stored into the blob. The default value is the empty string, ("").

This gets us far enough to understand this code in the linked answer:

var byteArray = new Uint8Array(arr);
//...

a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/octet-stream' }));

which is first creating a typed array of unsigned int8s, then wrapping that UInt8Array in an array and using it to construct a Blob with the specified MIME type.

In elemental2, we have these same constructors - but I think we're going to want to use a different TypedArray type here, since Java bytes are signed, so instead let's look at elemental2.core.Int8Array (also available at MDN for clearer documentation). We can either use a constructor to create an Int8Array, or can use the static from(...) method. Neither of these actually accept a byte[], but either want a double[] or JsArrayLike<Double> - from our perspective as Java developers, these seem wrong, but from JS's perspective a GWT byte[] is usually just a plain JS array that just happens to have small Numbers in it (which map to Java double or Double.

So we cheat, and cast to what we actually want. The rest of the code just deals with making arrays of union types, a corner case of Elemental2 and JsInterop that we usually don't have to look closely at.

public static Blob makeBlobFromBytes(byte[] byteArray) {

  // First, cast our incoming byte[] to something we can wrap in an Int8Array
  JsArrayLike<Double> data = Js.uncheckedCast(byteArray);

  // Then copy this data into a TypedArray
  Int8Array int8Array = Int8Array.from(data);

  // Finally wrap in a Blob, with the specified MIME type and other options.
  // This part is a bit irritating since we have to use a union in an array:
  BlobPropertyBag options = BlobPropertyBag.create();
  options.setType("application/octet-stream");
  Blob blob = new Blob(JsArray.of(
      Blob.ConstructorBlobPartsArrayUnionType.of(int8Array)
  ), options);
}
英文:

First, let's take a quick look at the MDN docs for Blob's constructor arguments:

> Parameters
>
> array - An iterable object such as an Array, having ArrayBuffers, TypedArrays, DataViews, Blobs, strings, or a mix of any of such
> elements, that will be put inside the Blob. Note that strings here are
> encoded as UTF-8, unlike the usual JavaScript UTF-16 strings.
> options (Optional) - An object which may specify any of the following properties:
>
> * type Optional - The MIME type of the data that will be stored into the blob. The default value is the empty string, ("").

This gets us far enough to understand this code in the linked answer:

var byteArray = new Uint8Array(arr);
//...

a.href = window.URL.createObjectURL(new Blob([byteArray], { type: &#39;application/octet-stream&#39; }));

which is first creating a typed array of unsigned int8s, then wrapping that UInt8Array in an array and using it to construct a Blob with the specified MIME type.

In elemental2, we have these same constructors - but I think we're going to want to use a different TypedArray type here, since Java bytes are signed, so instead let's look at elemental2.core.Int8Array (also available at MDN for clearer documentation). We can either use a constructor to create an Int8Array, or can use the static from(...) method. Neither of these actually accept a byte[], but either want a double[] or JsArrayLike&lt;Double&gt; - from our perspective as Java developers, these seem wrong, but from JS's perspective a GWT byte[] is usually just a plain JS array that just happens to have small Numbers in it (which map to Java double or Double.

So we cheat, and cast to what we actually want. The rest of the code just deals with making arrays of union types, a corner case of Elemental2 and JsInterop that we usually don't have to look closely at.

public static Blob makeBlobFromBytes(byte[] byteArray) {

  // First, cast our incoming byte[] to something we can wrap in an Int8Array
  JsArrayLike&lt;Double&gt; data = Js.uncheckedCast(byteArray);

  // Then copy this data into a TypedArray
  Int8Array int8Array = Int8Array.from(data);

  // Finally wrap in a Blob, with the specified MIME type and other options.
  // This part is a bit irritating since we have to use a union in an array:
  BlobPropertyBag options = BlobPropertyBag.create();
  options.setType(&quot;application/octet-stream&quot;);
  Blob blob = new Blob(JsArray.of(
      Blob.ConstructorBlobPartsArrayUnionType.of(int8Array)
  ), options);
}

huangapple
  • 本文由 发表于 2023年4月13日 21:55:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定