Java 程序与 Office Web Apps 整合

想要将自己的程序与Office Web Apps整合,关键在于提供如下两个接口:

1、CheckFileInfo服务,此服务会返回文件的基本信息

详情可参考[MS-WOPI] section3.3.5.1.1 章节

2、GetFile服务,此服务根据上一个服务返回的基本信息返回对应文件的数据流

详情可参考[MS-WOPI] section3.3.5.3.1 章节。

因此,只需要实现这两个接口即可保证office文档的在线浏览。我这里以Java为例,演示我是如何将两者整合的。

CheckFileInfo

此服务用于返回文档的基本信息,根据我的实践,这些基本信息只要包括如下几点即可:

  1. BaseFileName:文件名
  2. OwnerId:文件的拥有着(可以随便设置)
  3. Size:文档内容大小
  4. Version:文件的最后修改时间

我通过java提供的CheckFileInfo服务如下:

/**
 * 获取预览文档的信息
 * @param type 文档后缀
 * @param name 文档名称、ID等能标识文档的属性
 * @param access_token 令牌,用作校验用
 * @return 文档基本信息类 - OfficeFileInfo
 */
@RequestMapping(value ="/{type}/wopi/files/{name}")
public OfficeFileInfo CheckFileInfo(@PathVariable String type, 
                                    @PathVariable String name, 
                                    @RequestParam String access_token){
    //TODO: 仅仅Demo演示
    File file=new File("D:/demo/"+name+"."+type);
    return new OfficeFileInfo(file.getName(),file.length(),file.lastModified());
}

返回的JSON数据中,属性名一定要大写,OfficeFileInfo 文档基本信息类如下:

public class OfficeFileInfo {

    @JsonProperty(value="BaseFileName")
    private String baseFileName;
    
    @JsonProperty(value="OwnerId")
    private String ownerId;
    
    @JsonProperty(value="Size")
    private long size;
    
    @JsonProperty(value="Version")
    private long version;
    
    public OfficeFileInfo(){
    	this.ownerId = "admin";//随意设置
    }
    
    public OfficeFileInfo(String baseFileName,long size,long version){
    	this();
    	this.baseFileName = baseFileName;
    	this.size = size;
    	this.version = version;
    }
    
    public String getBaseFileName() {
    	return baseFileName;
    }
    public String getOwnerId() {
    	return ownerId;
    }
    public long getSize() {
    	return size;
    }
    public long getVersion() {
    	return version;
    }
    public void setBaseFileName(String baseFileName) {
    	this.baseFileName = baseFileName;
    }
    public void setOwnerId(String ownerId) {
    	this.ownerId = ownerId;
    }
    public void setSize(long size) {
    	this.size = size;
    }
    public void setVersion(long version) {
    	this.version = version;
    }
}

暴露出来的接口格式如下:

http://ip:port/App/rest/office/{type}/wopi/files/{name}?access_token=demo

我在对应的磁盘里放了一个1.docx文档,访问此服务,得到的结果为:

{
    "BaseFileName": "1.docx",
    "OwnerId": "admin",
    "Size": 871248,
    "Version": 1487241262462
}

如下图所示:

GetFile服务

此服务根据上一个服务返回的基本信息来请求文件流。此接口定义必须在前者的基础上再加上/contents,也就是如下格式:

http://ip:port/App/rest/office/{type}/wopi/files/{name}/contents?access_token=demo

因此,我的GetFile服务实现如下:

/**
 * 获取文档的数据流
 * 注意:此服务应该由office server 调用,自行调用可以禁止掉,否则此接口会变成下载接口
 * @param type 文档后缀
 * @param name 文档名称、ID等能标识文档的属性
 * @param access_token 令牌,用作校验用
 * @return 文档流
 */
@RequestMapping(value ="/{type}/wopi/files/{name}/contents")
public void GetFile(@PathVariable String type,  
                    @PathVariable String name,
                    @RequestParam String access_token,
                    HttpServletResponse response){
    try {
        //TODO: 仅仅Demo演示
        String filePath = "D:/demo/"+name+"."+type;
        InputStream fis = new FileInputStream(filePath);
        OutputStream os = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Length", "" + fis.available());
        byte[] buffer = new byte[1024];
        while(fis.read(buffer) != -1){
            os.write(buffer);
        }
        os.write(buffer);
        os.flush();
        fis.close();
        os.close();
    }catch (Exception e){
        e.printStackTrace();
    }
}

这样java程序即可与Office Web Apps整合了。