一、申请成为服务商,对金山文档在线服务进行申请

①进入官网 https://open.wps.cn/

②申请后如下图,点击右下角的进入服务

③申请成功后

④数据回调URL一定是服务器地址,本次我使用的是域名地址

完成上述步骤,就可以准备开发了

二、官方的技术文档一定要阅读

①简单介绍下运行流程

②我们需要做的,是在自己的应用程序中添加官方文档需要的接口如下图

③技术文档地址 http://open-doc.wps.cn/金山文档在线编辑/快速接入.html

三、了解运行机制以及需要的接口后,开始愉快的编码

本次的教程为demo,目的是为了能打开我们私有云存储的office文档,仅支持打开文档,其他功能后续编码。

示例代码仅提供 /v1/3rd/file/info 接口,其他的接口参照官方文档进行开发即可

①首先需要进行签名生成,每次打开文档的url都需要进行获取签名,签名是按照参数进行生成的

签名规则一定要参照官网文档,官方给的是JAVA版本,我们.NET的代码参考了其他博主的代码,整理后如下

/// <summary>
         /// 签名规则
         /// </summary>
         /// <param name="paras">参数</param>
         /// <param name="appId">申请的APPID</param>
         /// <param name="appSecret">申请的APPKEY</param>
         /// <returns></returns>

        public string Sign(Dictionary<string,string> paras,string appId,string appSecret) {string paraValue = string.Empty;
            //按照字典key进行排序
List<string> keys = paras.Keys.OrderBy(x=>x).ToList();
foreach (var key in keys)
{
                //过滤APPKEY参数,最后加上
if (key == "_w_secretkey")
{
continue;
}
paraValue += key + "="+paras[key];
}
            //APPKEY参数,最后加上
paraValue += "_w_secretkey=" + paras["_w_secretkey"];
var hmacshal = new HMACSHA1(Encoding.UTF8.GetBytes(appSecret));
var dataBuffer = Encoding.UTF8.GetBytes(paraValue);
var hashBytes = hmacshal.ComputeHash(dataBuffer);
string base64 = Convert.ToBase64String(hashBytes);
return HttpUtility.UrlEncode(base64);
}

测试,官网为例

官方提供的如下

"contents": "_w_appid=123456_w_fname=222.docx_w_userid=id1000_w_secretkey=7890"

"signature": "dL3ce9l0l+GKTz+i0R++H2qWwrQ=" (未URL编码)

我们需要做的,将contents部分切割成 Dictionary<string, string>传入

测试代码如下,调用上面的签名代码

        public string test1()
{
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("_w_appid", "");
d.Add("_w_fname", "222.docx");
d.Add("_w_userid", "id1000");
d.Add("_w_secretkey", "");
return Sign(d, "", "");
}

调用后生成的签名应该是和官网一致,官方的是未URL编码

我们上述Sign方法已进行URL编码,结果为 dL3ce9l0l+GKTz+i0R++H2qWwrQ%3d

特别注意,这只是我们的demo程序,非正式应用,所以真实运行场景一定不是我们这样子随意编码

②项目如果是普通的MVC,需要修改RouteConfig,启用Attribute路由,以实现 回调方法 如 /v1/3rd/file/info 这种形式(如果采用其他方式可忽略)

    public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes();//启用Attribute路由 routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

③ 接口 /v1/3rd/file/info 代码

        /// <summary>
/// 获取文件元数据
/// </summary>
/// <returns></returns>
[Route("v1/3rd/file/info")]
[HttpGet]
public JsonResult info(string _w_signature,string _w_appid)
{
var res = new JsonResult();
response_wpsModel wpsModel = new response_wpsModel(); userModel user = new userModel();
user.id = "";
user.name = "kls-dev";
            //用户权限
user.permission = "write";
user.avatar_url = "http://XXXXX.com/图片20180813135932.jpg";
fileModel f = new fileModel();
            //文件主键,要确保唯一
f.id = "id2019110609261";
f.name = "文件名.xlsx";
f.version = ;
f.size = ;
f.creator = user.name;
f.create_time= long.Parse(TimeHelper.GetCurrentTimestamp(false));
f.modifier = user.name;
f.modify_time =long.Parse(TimeHelper.GetCurrentTimestamp(false)) ;
            //文件的云地址
f.download_url = "http://XXXXX.com/Content/文件名.xlsx";
user_aclModel acl = new user_aclModel();
acl.rename = ;
acl.history = ;
f.user_acl = acl;
f.watermark =new watermarkModel(); wpsModel.file = f;
wpsModel.user = user;
return Json(wpsModel,JsonRequestBehavior.AllowGet);
} //补充时间戳帮助类

/// <summary>
/// 时间相关
/// </summary>
public static class TimeHelper
{
/// <summary>
/// 获取当前时间戳
/// </summary>
/// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
/// <returns></returns>
public static string GetCurrentTimestamp(bool millisecond = true)
{
return DateTime.Now.ToTimestamp(millisecond);
}


/// <summary>
/// 转换指定时间得到对应的时间戳
/// </summary>
/// <param name="dateTime"></param>
/// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
/// <returns>返回对应的时间戳</returns>
public static string ToTimestamp(this DateTime dateTime, bool millisecond = true)
{
return dateTime.ToTimestampLong(millisecond).ToString();
}


/// <summary>
/// 转换指定时间得到对应的时间戳
/// </summary>
/// <param name="dateTime"></param>
/// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
/// <returns>返回对应的时间戳</returns>
public static long ToTimestampLong(this DateTime dateTime, bool millisecond = true)
{
var ts = dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return millisecond ? Convert.ToInt64(ts.TotalMilliseconds) : Convert.ToInt64(ts.TotalSeconds);
}


/// <summary>
/// 转换指定时间戳到对应的时间
/// </summary>
/// <param name="timestamp">(10位或13位)时间戳</param>
/// <returns>返回对应的时间</returns>
public static DateTime ToDateTime(this string timestamp)
{
var tz = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
return timestamp.Length == 13
? tz.AddMilliseconds(Convert.ToInt64(timestamp))
: tz.AddSeconds(Convert.ToInt64(timestamp));
}
}

 

④需要用到的实体类

        /// <summary>
/// 返回的实体
/// </summary>
        public class response_wpsModel {
public fileModel file { get; set; }
public userModel user { get; set; }
}
/// <summary>
/// 文件属性
/// </summary>
public class fileModel
{
public string id { get; set; }
public string name { get; set; }
public int version { get; set; }
public int size { get; set; }
public string creator { get; set; }
public long create_time { get; set; }
public string modifier { get; set; }
public long modify_time { get; set; }
public string download_url { get; set; }
public user_aclModel user_acl { get; set; }
public watermarkModel watermark { get; set; } }
/// <summary>
/// 用户权限
/// </summary>
public class user_aclModel
{
public int rename { get; set; }
public int history { get; set; }
}
/// <summary>
/// 水印
/// </summary>
public class watermarkModel
{
private static int _type = ;
public int type {
get { return _type; }
set { _type = value;}
}
private static string _value = "公司名称";
public string value
{
get { return _value; }
set { _value = value; }
}
private static string _fillstyle = "rgba( 192, 192, 192, 0.6)";
public string fillstyle
{
get { return _fillstyle; }
set { _fillstyle = value; }
}
private static string _font = "bold 20px Serif";
public string font
{
get { return _font; }
set { _font = value; }
}
private static double _rotate = -0.7853982;
public double rotate
{
get { return _rotate; }
set { _rotate = value; }
}
private static int _horizontal = ;
public int horizontal
{
get { return _horizontal; }
set { _horizontal = value; }
}
private static int _vertical = ;
public int vertical
{
get { return _vertical; }
set { _vertical = value; }
}
}
/// <summary>
/// wps用户实体
/// </summary>
public class userModel {
public string id { get; set; }
public string name { get; set; }
public string permission { get; set; }
public string avatar_url { get; set; }
}

⑤程序发布到服务器后,在线打开我们的文档,下面的url是Excel的,具体的还是要参考官方文档

https://wwo.wps.cn/office/s/<文件主键>?_w_fname=文件名.xlsx&_w_userid=<代码中用户id576590854>&_w_appid=<APPID>&_w_permission=write&_w_signature=<第一步生成的签名,写在这里YvaZvg8Aw0yTPZG7ZZNTERscWDA%3d>

好了,可以愉快的在线打开office文档了。

wps金山文档在线编辑--.Net 接入指南的更多相关文章

  1. Office文档在线编辑的实现之二

    讲述了如何通过iis的webdav支持实现客户端的office直接编辑服务器上的文件,本篇将讲解如何实现客户端的office直接编辑数据库中的二进制形式保存的office文件. 实现的关键:模拟IIS ...

  2. Office文档在线编辑的实现之一

    因为项目的关系,研究了一下Office的在线编辑功能,写出来共享一下. Office xp之后的版本支持通过webdav协议(http的扩展)直接编辑服务器上的文件. IIS(6.0)支持webdav ...

  3. 使用WebDAV实现Office文档在线编辑

    Office的文档处理能力是非常强大的,但是它是本地资源,在Office Web App尚未成熟前,仍需要使用本地能力来进行文档编辑,可是现代的系统的主流却是B/S,所以在B/S中调用本地的Offic ...

  4. web文档在线阅览

    之前遇到很多各种文档在线阅览的需求,也有不少朋友经常问我这种需求的实现方案,大致试了一下网上的一些比较主流的推荐方案,但都不尽如人意,这里有一个比较全面的总结,需要的朋友可以根据自己的需求到这里查看, ...

  5. 如何破解Excel文档的编辑密码

    对于Excel文档我们不仅可以设置打开密码,还可以设置几天几种密码,比如编辑密码.编辑密码又称写保护密码,是一种可以限制编辑权限的密码.如果我们在日常工作中发现自己忘记了excel编辑密码的话,那就需 ...

  6. 基于Metronic的Bootstrap开发框架经验总结(17)-- 使用 summernote插件实现HTML文档的编辑和图片插入操作

    在很多场合,我们需要在线编辑HTML内容,然后在页面上或者其他终端上(如小程序.APP应用等)显示,编辑HTML内容的插件有很多,本篇介绍基于Bootstrap的 summernote插件实现HTML ...

  7. 最好用的js前端框架、组件、文档在线预览插件

    这里收集的都是个人认为比较好的js框架.组件 js前端ui框架 此处列举出个人认为最好的几个框架(排序即排名),现在好点的框架商用都需要付费,以下几个也不例外,但是由于组件丰富,都可以作为企业应用的完 ...

  8. 简单删除我的电脑里的wps云文档图标

    装个wps,用着都挺好,我的电脑一直存在wps云文档的图标. 看久了就觉得很膈应,那就直接干掉吧. 桌面新建一个文本文件,选中新建文本文档.txt 按f2 然后修改为11.reg(任意名称只要保证后缀 ...

  9. asp.net 将word文档进行编辑并导出一个新的word

    最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...

随机推荐

  1. Python+OpenCV4:读写输入和输出的简单实践(图片、视频、摄像头)

    典型的文件处理流程如下: 利用命令行参数 sys.argv 命令行参数是读取文件时常用的方式. 命令行参数保存在 sys.argv 的列表中,列表的第一个元素是脚本名称,后面的元素是命令行参数: 通过 ...

  2. 201871010135 张玉晶 《面向对象程序设计(java)》第二周学习总结

    201871010135 张玉晶 <面向对象程序设计(java)>第二周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  3. 201871020225-牟星源《面向对象程序设计(JAVA)》第二周学习总结

    正文: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-dai ...

  4. bloginfo()用法小结|wordpress函数

    bloginfo()显示关于您的wordpress站点的信息,主要是从您的用户配置文件和WordPress管理屏幕的一般设置中收集的信息.它可以在模板文件的任何地方使用.这总是将结果打印到浏览器.如果 ...

  5. Django 购物车模板

    url from django.contrib import admin from django.urls import path, re_path from django.urls import i ...

  6. 产品上线后,出现BUG的处理流程

    根据bug的大小,如果影响业务逻辑及用户提醒及时处理,如果只是一些状态.文案等等对业务无重大影响可以跟版本迭代走 很严重的bug必然要回滚,想都不要想赶紧去着手安排做. 检查回滚版本是否会丢失数据,如 ...

  7. Flask常用路由参数

    Flask中的路由参数: @app.route(‘/’, endpoint=’xx’ , methods=[‘GET’,...]) >endpoint后的名字,用来反向生成url的.后面的名字随 ...

  8. [NOI2010]超级钢琴 主席树

    [NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样. 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #defi ...

  9. 面试必问:HashMap 底层实现原理

    HashMap是在面试中经常会问的一点,很多时候我们仅仅只是知道HashMap他是允许键值对都是Null,并且是非线程安全的,如果在多线程的环境下使用,是很容易出现问题的. 这是我们通常在面试中会说的 ...

  10. 《Linux就该这么学》培训笔记_ch13_使用Bind提供域名解析服务

    <Linux就该这么学>培训笔记_ch13_使用Bind提供域名解析服务 文章最后会post上书本的笔记照片. 文章主要内容: DNS域名解析服务 安装并部署Bind服务程序 部署从服务器 ...