使用 Spark 将内存中生成的 .docx 文件从服务器发送到客户端
Sending in-memory generated .docx files from server to client with Spark
我正在使用 Spark Java framework 创建 Web 应用程序。前端使用AngularJS.
开发
我想在服务器上(内存中)生成一个 .docx 文件并将其发送到客户端以供下载。
为此,我创建了一个 angular 服务,在用户单击下载按钮后调用以下函数:
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey).success(function (response) {
var element = angular.element('<a/>');
element.attr({
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response,
target: '_blank',
download: 'test.docx'
})[0].click();
});
};
在服务器上,此 api 调用被转发到以下方法:
public Response exportToWord(Response response) {
try {
File file = new File("src/main/resources/template.docx");
FileInputStream inputStream = new FileInputStream(file);
byte byteStream[] = new byte[(int)file.length()];
inputStream.read(byteStream);
response.raw().setContentType("data:attachment;chatset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.raw().setContentLength((int) file.length());
response.raw().getOutputStream().write(byteStream);
response.raw().getOutputStream().flush();
response.raw().getOutputStream().close();
return response;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
我已经尝试通过许多不同的方式解决这个问题,但我总是以损坏的 'test.docx' 结束,看起来像这样:
通过使用 blob 并在 $http.post api 调用中将响应类型指定为 'arraybuffer' 解决了该问题。这个解决方案的唯一缺点(据我所知)是它不能很好地与 IE 兼容,但那是以后的问题。
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey, {responseType: 'arraybuffer'})
.success(function (response) {
var blob = new Blob([response], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var element = angular.element('<a/>');
element.attr({
href: url,
target: '_blank',
download: 'survey.docx'
})[0].click();
});
};
我认为出了问题是当我尝试创建 URL 时字节流被编码为纯文本:
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response
从而破坏它。
当使用 blob 时,我得到一个 "direct" link 到生成的字节流,并且没有对其进行编码,因为响应类型设置为 'arraybuffer'。
请注意,这只是我自己对原始代码出错原因的推理。我可能错得离谱,如果是这样,请随时纠正我。
我正在使用 Spark Java framework 创建 Web 应用程序。前端使用AngularJS.
开发我想在服务器上(内存中)生成一个 .docx 文件并将其发送到客户端以供下载。
为此,我创建了一个 angular 服务,在用户单击下载按钮后调用以下函数:
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey).success(function (response) {
var element = angular.element('<a/>');
element.attr({
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response,
target: '_blank',
download: 'test.docx'
})[0].click();
});
};
在服务器上,此 api 调用被转发到以下方法:
public Response exportToWord(Response response) {
try {
File file = new File("src/main/resources/template.docx");
FileInputStream inputStream = new FileInputStream(file);
byte byteStream[] = new byte[(int)file.length()];
inputStream.read(byteStream);
response.raw().setContentType("data:attachment;chatset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.raw().setContentLength((int) file.length());
response.raw().getOutputStream().write(byteStream);
response.raw().getOutputStream().flush();
response.raw().getOutputStream().close();
return response;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
我已经尝试通过许多不同的方式解决这个问题,但我总是以损坏的 'test.docx' 结束,看起来像这样:
通过使用 blob 并在 $http.post api 调用中将响应类型指定为 'arraybuffer' 解决了该问题。这个解决方案的唯一缺点(据我所知)是它不能很好地与 IE 兼容,但那是以后的问题。
functions.generateWord = function () {
$http.post('/api/v1/surveys/genword', data.currentSurvey, {responseType: 'arraybuffer'})
.success(function (response) {
var blob = new Blob([response], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'});
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var element = angular.element('<a/>');
element.attr({
href: url,
target: '_blank',
download: 'survey.docx'
})[0].click();
});
};
我认为出了问题是当我尝试创建 URL 时字节流被编码为纯文本:
href: 'data:attachment;charset=utf-8;application/vnd.openxmlformats-officedocument.wordprocessingml.document' + response
从而破坏它。
当使用 blob 时,我得到一个 "direct" link 到生成的字节流,并且没有对其进行编码,因为响应类型设置为 'arraybuffer'。
请注意,这只是我自己对原始代码出错原因的推理。我可能错得离谱,如果是这样,请随时纠正我。