【问题标题】:Save Word document (.docx) using Office.js API to back-end server使用 Office.js API 将 Word 文档 (.docx) 保存到后端服务器
【发布时间】:2015-06-23 19:46:51
【问题描述】:

我在将 byte 数组(使用 Office.js 从 Microsoft Office 的任务窗格中获取)保存到 Word 文档文件(在服务器端)时遇到了一些麻烦。这就是我正在做的:

  • 我正在使用library 获取 Word 文档的内容

JavaScript

$('#push').click(function () {
  $.when(OffQuery.getContent({ sliceSize: 1000000 }, function (j, data, result, file, opt) {
    // ...nothing interesting here
  })).then(function (finalByteArray, file, opt) {
    // (1) this line is changed...see the answer
    var fileContent = Base64.encode(finalByteArray); //encode the byte array into base64 string.

    $.ajax({
      url: '/webcontext/api/v1/documents',
      // (2) missing setting (see the answer)
      data: fileContent,
      type: 'POST'
    }).then(function () {
      // updateStatus('Done sending contents into server...');
    });
  }).progress(function(j, chunkOfData, result, file, opt){
    // ...nothing interesting here
});
  • 然后在 Spring 控制器中我这样做:

Java/Spring

@RequestMapping(method = RequestMethod.POST) // As OOXML
public void create(@RequestBody String fileContent, HttpServletRequest request) throws Exception { // TODO
  LOGGER.debug("{} {}", request.getMethod(), request.getRequestURI());
  //LOGGER.debug("fileContent: {}", fileContent);
  try {
    val base64 = Base64.decodeBase64(fileContent); // From Apache Commons Codecs

    FileUtils.writeByteArrayToFile(new File("assets/tests/output/some_file.docx"), base64);
  } catch (IOException e) {
    LOGGER.error("Crash! Something went wrong here while trying to save that...this is why: ", e);
  }
}

...但是文件按原样保存;基本上是将byte 数组作为文本文档保存到文件中。

我错过了什么吗?你有什么线索吗?有人使用过 Office.js、任务窗格和类似的东西吗?

提前谢谢...

更新 1

原来finalByteArray 正在转换为 Base64 字符串 (fileContent),但是当我尝试在 Java 中执行反向操作时不起作用...如果有人之前这样做过,请告诉我知道。我试过了:

  1. Mozilla 页面中的示例
  2. Unibabel
  3. base64-js

...在 Java 端(将 Base64 String 解码为 byte 数组):

  1. 默认Base64编码器/解码器
  2. Base64 Apache codec

【问题讨论】:

  • 什么是base64变量实数数据类型?
  • @stiv 它的类型为byte[]
  • 如果是我,我会将“val”更改为“byte[]”,看看会发生什么。接下来,我将发送一个简单的 docx 文件(不使用 Office.js),然后将副本与原始文件进行比较。如果可行,则问题出在 Office.js 生成的文件上。这里有一些使用 Office.js 发送 docx 文件的 MS 示例:Get the whole document“为 Word 创建一个任务窗格应用程序,该应用程序可以引用所有当前文档的内容并将其发送到 Web 服务器。”
  • 为什么在解码的时候把fileContent的最后一个字符截掉?
  • 请记录 base64 长度和输出文件长度并在此处报告。

标签: javascript java spring ms-office openxml


【解决方案1】:

实际上,我发现了错误。它在客户端。 Office.js SDK 中包含一个函数,可以将 byte 数组转换为 Base64 string —— 虽然我不确定它是否随所有版本一起提供,但我' m 使用 Office.js SDK 1.1

所以我把转换改为:

var fileContent = OSF.OUtil.encodeBase64(finalByteArray);

...在 AJAX 调用中,我添加了 contentType 设置:

  $.ajax({
    //...
    contentType: 'application/octet-stream',
    // ...
    type: 'POST'
  }).finish(function () {
    // ...
  });

通过正确设置内容类型,我能够将“正确的内容”发布到服务器。

即使我在没有设置正确的情况下进行了正确的 Base64 转换 Content Type,Spring控制器中接收到的数据是 与客户端报告的不同(在这种情况下更大) 一边。

我希望这可以在将来对其他人有所帮助。 Microsoft Web 中的示例非常清楚,但出于某种原因“环境之间总是存在一些差异”。

【讨论】:

    【解决方案2】:

    您的代码中没有明显的错误,除了(如注释)我不知道您为什么从代码中删除最后一个字符。

    您为什么不使用像 Firebug 这样的 javascript 调试器和用于 Web 服务器的远程 Java 调试器来检查处理中的每个步骤并控制各种变量的内容(Javascript 文件内容、Java 文件内容、Java base64)以找出答案错误蔓延的地方。

    【讨论】:

    • 它们是相同的:在 JavaScript 代码中,base64 转换与我在 Java 代码中收到的匹配;甚至 byte 数组内容;但由于某种原因,每当我将这些字节保存在文件中时,它都会按原样保存(请参阅原始问题的更新 1)
    • 所以只是 FileUtils.writeByteArrayToFile(new File("assets/tests/output/some_file.docx"), base64);失败了吗?
    • 这不是“它失败了”,而是它没有创建我想要的正确内容......每当我尝试打开(已经创建的).docx 文档时,Word 都会说“它已损坏"
    • 这是一个新信息。为什么不回到基础,获取一个现有的 word 文件,将其读入 byte[] 区域,对其进行编码、解码并再次写出,只是为了确保基础工作正常,不涉及任何网络设想。顺便说一句,为什么要从 fileContent 变量中截掉最后一个字符?
    • 您终于自己发现了错误,太好了!祝你的项目好运
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2016-01-02
    相关资源
    最近更新 更多