wpsOffice文件在线预览-java接入

wpsOffice文件在线预览

wpsoffice开发文档地址:https://wwo.wps.cn/docs/
hint:申请服务通过后需填写回调地址,请填写你的服务器公网可访问的地址。
并且项目需要部署到你的公网可访问的服务器上。

一:添加model类

由于官方demo是完全无需引入依赖的,所以可将model包下类直接复制到自己项目中

//model类1
@Component
public class ApplicationProperties implements CommandLineRunner {

    public static String appid = "";
    public static String appSecret = "";
    public static String domain = "";

    @Autowired
    public ApplicationProperties(
            @Value("${appid}") String appid,
            @Value("${appsecret}") String appSecret,
            @Value("${download_host}") String download_host,
            @Value("${domain}") String domain) {
        ApplicationProperties.appid = appid;
        ApplicationProperties.appSecret = appSecret;
        ApplicationProperties.domain = domain;
         TODO: 下载链接按实际情况增改参数
//        if (download_host != null)
//            FileModel.download_url = download_host + "/weboffice/getFile?_w_fileid=";
    }

    @Override
    public void run(String... args) throws Exception {

    }
}

public class FileInfoModel {
    FileModel file = new FileModel();
    UserModel user = new UserModel();

}
//值是自定义的,我测试用的顺便写的参数
public class FileModel {
    public String id = "111";
    public String name = "1.doc";
    public long version = 3;
    public long size = 2000;
    public String creator = "1231";
    public String modifier = "1231";
    public static String download_url = "";
}

public class UrlModel {
    public String wpsUrl;
    public String token;
}

public class UserModel {
    public String id = "xxx";
    public String name ="xxx";
    public String permission = "read";  //read-在线预览  write-在线编辑
    public String avatar_url = "xxx";
}

二:配置文件application.yml

domain: https://wwo.wps.cn #无需改动
appid: xxx
appkey:   xxx
download_host: xxx #根据需要配置
appsecret: xxx  #用于加密的盐,自定义

三:实现回调接口

3.1-根据文件id生成wps的url

@RestController
public class OauthController  {
    
    //自定义的ppt服务接口,用于在数据库中维护文件信息
    @Autowired
    private IPptFileService pptFileService;
    private static Map<String, String> fileTypeMap = new HashMap<String, String>();
     TODO: 参数传递最好不要出现中文等特殊字符,容易导致签名不过等问题,本例子用fileid与文件名做了一个映射,实际开发可以按情况处理
    static {
        fileTypeMap.put("1", "w");
        fileTypeMap.put("2", "s");
        fileTypeMap.put("3", "p");
        fileTypeMap.put("4", "f");
    }
//    @PassToken
    @RequestMapping(value="/weboffice/url", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult getapp_Token(@RequestParam("_w_fileid") String fileid) throws UnsupportedEncodingException {
        if (fileid == null || fileid.isEmpty()) {
            return null;
        }
        LambdaQueryWrapper<PptFile> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(PptFile::getFileKey,fileid);
        PptFile one = pptFileService.getOne(queryWrapper);
        if(one.getFileId()!=null){
            fileid=one.getFileId();
        }else{
            UUID uuid = UUID.randomUUID();
            String replace = uuid.toString().replace("-", "");
            one.setFileId(replace);
            one.setUpdateTime(new Date());
            fileid=replace;
            pptFileService.updateById(one);
        }
        String url = ApplicationProperties.domain + "/office/" + "p" + "/" + fileid + "?" ;
         TODO: 注意:签名前,参数不要urlencode,要签名以后统一处理url编码,防止签名不过,带中文等字符容易导致签名不过,要注意签名与编成的顺序,最好不要带中文等特殊字符
        Map paramMap= new HashMap<String, String>();
        paramMap.put("_w_appid", ApplicationProperties.appid);
        paramMap.put("_w_fileid", fileid);
        String signature = getSignature(paramMap, ApplicationProperties.appSecret);
        url += getUrlParam(paramMap) + "&_w_signature=" + signature;
        UrlModel urlModel = new UrlModel();
        urlModel.wpsUrl = url;
        urlModel.token = "abc";
        return CommonResult.success(urlModel);
    }

    private static String getUrlParam(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (builder.length() > 0) {
                builder.append('&');
            }
            builder.append(URLEncoder.encode(entry.getKey(), "utf-8")).append('=').append(URLEncoder.encode(entry.getValue(), "utf-8"));
        }
        return  builder.toString();
    }

    private static String getSignature(Map<String, String> params, String appSecret) {
        List<String> keys=new ArrayList();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            keys.add(entry.getKey());
        }

         // 将所有参数按key的升序排序
        Collections.sort(keys, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

        // 构造签名的源字符串
        StringBuilder contents=new StringBuilder("");
        for (String key : keys) {
            if (key=="_w_signature"){
                continue;
            }
            contents.append(key+"=").append(params.get(key));
            System.out.println("key:"+key+",value:"+params.get(key));
        }
        contents.append("_w_secretkey=").append(appSecret);

        // 进行hmac sha1 签名
        byte[] bytes= hmacSha1(appSecret.getBytes(),contents.toString().getBytes());
        //字符串经过Base64编码
        String sign= encodeBase64String(bytes);
        try {
            sign = URLEncoder.encode( sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(sign);
        return sign;
    }

    public static byte[] hmacSha1(byte[] key, byte[] data) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
            Mac mac = Mac.getInstance(signingKey.getAlgorithm());
            mac.init(signingKey);
            return mac.doFinal(data);
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3.2-文件信息回调接口

@RestController
public class WebOfficeController {
    @Autowired
    private IPptFileService pptFileService;
    
 	//我在项目中使用了腾讯云存储服务,需要了解接入腾讯云存储的朋友可看我腾讯云存储的文章
    //url:https://blog.csdn.net/qq_50990903/article/details/118615261?spm=1001.2014.3001.5501
    @Autowired
    private QCloudStorageService storageService;
    @Autowired
    private TencentCosConfig tencentCosConfig;
    @Autowired
    private COSClient cosStsClient;
     TODO: 参数传递最好不要出现中文等特殊字符,容易导致签名不过等问题,本例子用fileid与文件名做了一个映射,实际开发可以按情况处理
    private static Map<String, String> fileNameMap = new HashMap<String, String>();

    static {
        fileNameMap.put("1", "中文.doc");
        fileNameMap.put("2", "2.xls");
        fileNameMap.put("3", "3.ppt");
    }
    @PassToken
    @RequestMapping(value="/v1/3rd/file/info", method = RequestMethod.GET)
    @ResponseBody
    public Object fileInfo(@RequestParam("_w_fileid") String fileid) throws Exception {
        JSONObject jsonObject = new JSONObject();
        JSONObject file = new JSONObject();
        JSONObject user = new JSONObject();
        LambdaQueryWrapper<PptFile> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(PptFile::getFileId,fileid);
        PptFile one = pptFileService.getOne(queryWrapper);
        try {
            FileModel fileModel = new FileModel();
             TODO: 文件的id应该唯一
            file.put("id", fileid);
            file.put("name", fileid);
             TODO: 文件的版本控制
            file.put("version", fileModel.version);
             TODO: 必须返回文件真实大小,服务端会检查
            file.put("size", one.getFileSize());
            file.put("create_time",new Date().getTime()/1000);
            file.put("modify_time",new Date().getTime()/1000);
            file.put("creator", fileModel.creator);
            file.put("modifier", fileModel.modifier);
             TODO: 下载链接中的参数如带中文等特殊字符,参数必须进行urlencode
            //从腾讯云获取下载链接
            Date date = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
            URL url = cosStsClient.generatePresignedUrl(tencentCosConfig.getQcloudBucketName(), one.getFileKey(), date);
            String download_url=url.toString();
            file.put("download_url", download_url);
            jsonObject.put("file", file);
            UserModel userModel = new UserModel();
            user.put("id", userModel.id);
            user.put("name", userModel.name);
            user.put("permission", "read");
            user.put("avatar_url", userModel.avatar_url);
            jsonObject.put("user", user);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonObject.toString();
    }
    @PassToken
    @RequestMapping(value="/v1/3rd/file/version/{version}", method = RequestMethod.GET)
    @ResponseBody
    public Object fileVersionInfo(@PathVariable("version") Long version, @RequestParam("_w_fileid") String fileid) throws UnsupportedEncodingException {
        JSONObject jsonObject = new JSONObject();
        JSONObject file = new JSONObject();
        JSONObject user = new JSONObject();
        try {
            FileModel fileModel = new FileModel();
            File localFile = new File(fileNameMap.get(fileid));
            fileModel.size = localFile.length();
             TODO: 文件的id应该唯一
            file.put("id", fileid);
            file.put("name", fileNameMap.get(fileid));
             TODO: 文件的版本控制
            file.put("version", version);
             TODO: 必须返回文件真实大小,服务端会检查
            file.put("size", fileModel.size);
            file.put("creator", fileModel.creator);
            file.put("modifier", fileModel.modifier);
             TODO: 下载链接中的参数如带中文等特殊字符,参数必须进行urlencode
            file.put("download_url", fileModel.download_url + fileid);
            jsonObject.put("file", file);
            UserModel userModel = new UserModel();
            user.put("id", userModel.id);
            user.put("name", userModel.name);
            user.put("permission", "write");
            user.put("avatar_url", userModel.avatar_url);
            jsonObject.put("user", user);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonObject.toString();
    }
    @PassToken
    @RequestMapping(value="/v1/3rd/user/info", method = RequestMethod.POST)
    @ResponseBody
    public Object userInfo() {
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        JSONObject user = new JSONObject();
        UserModel userModel = new UserModel();
        try {
            user.put("id", userModel.id);
            user.put("name", userModel.name);
            user.put("permission", userModel.permission);
            user.put("avatar_url", userModel.avatar_url);
            jsonArray.put(user);
            jsonObject.put("users", jsonArray);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonObject.toString();
    }
    @PassToken
    @RequestMapping(value="/v1/3rd/file/online", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult online() {
        return CommonResult.success();
    }

    @PassToken
    @RequestMapping(value = "/v1/3rd/file/save", method = RequestMethod.POST)
    @ResponseBody
    public Object save(@RequestParam("file") MultipartFile file, @RequestParam("_w_fileid") String fileid) {
        if (!file.isEmpty()) {
            try {
                BufferedOutputStream out = new BufferedOutputStream(
                        new FileOutputStream(new File(fileNameMap.get(fileid))));
                out.write(file.getBytes());
                out.flush();
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         TODO: 返回保存后的文件信息 特别是文件大小与版本信息要准确
        FileModel filemodel = new FileModel();
        filemodel.name = fileNameMap.get(fileid);
        filemodel.size = file.getSize();
        filemodel.version = filemodel.version + 1;
        return filemodel;
    }
    
    /**
     * 回调通知
     */
    @PostMapping("v1/3rd/onnotify")
    public CommonResult onNotify() {
//        logger.info("回调通知param:{}", JSON.toJSONString(obj));
        // TODO
        // 返回数据暂不处理
        return CommonResult.success();
    }
    /*@PassToken
    @GetMapping("/weboffice/getFile")
    public ResponseEntity<byte[]> getFile(@RequestParam("_w_fileid") String fileid) throws Exception {
         TODO: 处理文件下载,返回对应的文件,如果是接第三方存储,可以没有这个接口
        File file = new File(fileNameMap.get(fileid));
        InputStream inputStream = new FileInputStream(file);
        byte[] body = new byte[inputStream.available()];
        HttpHeaders headers=new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileNameMap.get(fileid), "utf-8"));
        inputStream.read(body);
        return new ResponseEntity(body, headers, HttpStatus.OK);
    }*/
}
  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
你可以使用Java调用WPS来另存为DBF文件。以下是一种可能的实现方式: 1. 首先,确保你已经安装了WPSJava开发环境。 2. 使用Java的Runtime类来执行WPS的命令行操作。例如,你可以使用以下代码来打开WPS: ```java String wpsPath = "C:\\Program Files\\WPS Office\\ksolaunch.exe"; Runtime.getRuntime().exec(wpsPath); ``` 请确保将`wpsPath`变量设置为正确的WPS可执行文件路径。 3. 接下来,使用Java的Robot类来模拟键盘和鼠标操作,以便在WPS中进行操作。例如,你可以使用以下代码来模拟按下快捷键Ctrl+S来保存文件: ```java Robot robot = new Robot(); robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_S); robot.keyRelease(KeyEvent.VK_CONTROL); robot.keyRelease(KeyEvent.VK_S); ``` 请注意,这只是模拟了按下快捷键,你还需要根据WPS的界面和操作进行相应的调整。 4. 当WPS的保存文件对话框打开后,你可以使用Robot类来模拟键盘输入和按下回车键来设置文件保存路径和文件名。例如,你可以使用以下代码来设置文件名为"example.dbf"并保存: ```java String fileName = "example.dbf"; for (char c : fileName.toCharArray()) { robot.keyPress((int) c); robot.keyRelease((int) c); } robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); ``` 同样地,你需要根据WPS的界面和操作进行调整。 5. 最后,使用Robot类来模拟按下回车键以保存文件并退出WPS: ```java robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); ``` 请注意,这只是一个基本的示例,你可能需要根据你所使用的WPS版本和界面进行相应的调整。此外,使用Robot类进行模拟操作可能会有一定的风险和局限性,因此请谨慎使用并进行适当的测试和验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值