.Net Core集成Office Web Apps(二)

来源:http://www.cnblogs.com/liuxiaobo93/archive/2016/09/02/5834059.html
-Advertisement-
Play Games

想要使用OWA需要一臺單獨的伺服器來部署,這對很多人造成困難。而寫該文的目的是為了分享有個OWA的集成步驟,它不僅適用於.Net開發環境,其它語言也是一樣的,只要實現了需要的服務介面。並且該文不局限與OWA的研究,還包括Config、XML、Cache、Redis等技術。更重要的是熟悉.Net Co ...


想要使用OWA需要一臺單獨的伺服器來部署,這對很多人造成困難。而寫該文的目的是為了分享有個OWA的集成步驟,它不僅適用於.Net開發環境,其它語言也是一樣的,只要實現了需要的服務介面。並且該文不局限與OWA的研究,還包括ConfigXMLCacheRedis等技術。更重要的是熟悉.Net Core開發。

OwaFileInfoSupportsUpdateUserCanWriteSupportsLocks屬性為true時將允許用戶線上編輯文件。

在原有的基礎上編輯一個test.xlsx文件,其訪問鏈接為(測試鏈接沒有實際意義):http://owa.test.com/x/_layouts/xlviewerinternal.aspx?edit=1&WOPISrc=http%3a%2f%2f192.168.1.1%2fapi%2fwopi%2ffiles%2ftest.xlsx&access_token=H7lFBYT4pVMK

將彈出如下對話框

點擊編輯副本

 

查看請求日誌發現,另存副本請求將調用PutRelativeFile服務,所有我們應該再原來的基礎上添加PutRelativeFile服務。

PutRelativeFile服務

PutRelativeFile操作將在主機上創建一個基於當前文件的副本文件,創建成功後必須將副本文件名及URL以Json的格式返回給OWA伺服器。

如果OWA客戶端設置了CheckFileInfo的SupportsUpdate為true的話,就必須要實現PutRelativeFile服務,否則需要設置UserCanNotWriteRelative為true並且返回501狀態碼。

Method:POST

URI:HTTP://server/<...>/wopi*/files/<id>

 

Request Headers:

X-WOPI-Override 固定值 PUT_RELATIVE

X-WOPI-SuggestedTarget 文件擴展名或全名(可修改)

X-WOPI-RelativeTarget 文件全名(不可更改)

X-WOPI-OverwriteRelativeTarget 是否覆蓋文件名

X-WOPI-Size 文件的大小bytes

X-WOPI-FileConversion 指示請求是否轉換文件

Response Headers:

X-WOPI-ValidRelativeTarget

X-WOPI-Lock

X-WOPI-LockFailureReason

 

該介面需要返回的Json格式如下:

{Name:”test.xlsx”,Url:” http://server/<...>/wopi/files/ test.xlsx”, HostViewUrl :””, HostEditUrl :””}

 

說明:Name為新的文件名(如果修改的話),Url為新的文件的CheckFileInfo服務路徑。

線上Excel用到這個服務的情況有兩種:

1.另存為,如果沒有實現PutRelativeFile服務,則另存為將不能使用;

2.當編輯伺服器不支持的Excel某些格式的文件時,會先保存一個系統支持格式的副本,如果沒有實現PutRelativeFile服務,則不能編輯該Excel(因為保存新文件會失敗);

 

PutRelativeFile服務與CheckFileInfo服務的URL是相同的,只是Method不同,所以我們只需在CheckFileInfo的基礎上修改。

        [RouteAttribute("files/{name}")]
        public JsonResult GetFileInfo(string name, string access_token)
        {
            string wopiType = Request.Headers["X-WOPI-Override"];
            Console.WriteLine("1.X-WOPI-Override:" + wopiType);
            if (wopiType == "PUT_RELATIVE")
            {
                using (FileStream fs = System.IO.File.Create("Files/new_" + name))
                {
                    Request.Body.CopyTo(fs);
                }
                Response.Headers.Add("X-WOPI-ValidRelativeTarget", "new_" + name);
                Response.Headers.Add("X-WOPI-Lock", Request.Headers["X-WOPI-Lock"]);
                Response.StatusCode = 200;
                PutRelativeFile file = new PutRelativeFile();
                file.Name = "new_" + name;
                file.Url = "http://b1wcfoqm7r.proxy.qqbrowser.cc/api/wopi/files/new_" + name;
                return Json(file);
            }
            else if (wopiType == "UNLOCK" || wopiType == "LOCK")
            {
                Response.Headers.Add("X-WOPI-Lock", Request.Headers["X-WOPI-Lock"]);
                Response.StatusCode = 200;
                return Json("");
            }
            else
            {
                FileHelper helper = new FileHelper();
                var info = helper.GetFileInfo(name);
                info.SupportsUpdate = true;
                info.SupportsLocks = true;
                info.UserCanWrite = true;
                return Json(info);
            }
GetFileInfo
    [DataContract(Name = "PutRelativeFile")]
    public class PutRelativeFile
    {
        [DataMember(Name = "Name")]
        public string Name { get; set; }
        [DataMember(Name = "Url")]
        public string Url { get; set; }
        [DataMember(Name = "HostViewUrl")]
        public string HostViewUrl { get; set; }
        [DataMember(Name = "HostEditUrl")]
        public string HostEditUrl { get; set; }
    }
PutRelativeFile

Discovery.xml

訪問OWA伺服器的如下地址:http://owa.host.com/hosting/discovery(該鏈接無實際意義)就能得到OWA伺服器能夠處理的所有文件格式、操作及相關的URL。

<action name="view" ext="xls" default="true" urlsrc="http://owa.hand-china.com/x/_layouts/xlviewerinternal.aspx?<ui=UI_LLCC&><rs=DC_LLCC&>"/>

name=”view”表示動作為查看,ext=”xls”表示文件擴展名為xls,urlsrc則表示相應動作的地址。

以預覽test.xls為例,其ChecFileInfo路徑為:http://localhost:5000/api/wopi/files/test.xls

則最終預覽的鏈接為:http://owa.host.com/x/_layouts/xlviewerinternal.aspx?WOPISrc=http://localhost:5000/api/wopi/files/test.xls

我將OWA服務提交的discovery內容放到了本地的xml文件中,讀取方法如下:

        public static List<DiscoveryAction> GetDiscoveryAction()
        {
            List<DiscoveryAction> list = new List<DiscoveryAction>();
            XmlReader reader = XmlReader.Create("Files/Discovery.xml");
            //迴圈Read方法直到文檔結束  
            while (reader.Read())
            {
                //Console.WriteLine("rdr.NodeType = " + reader.NodeType);
                //如果是開始節點  
                if (reader.NodeType == XmlNodeType.Element)
                {
                    //通過rdr.Name得到節點名  
                    string elementName = reader.Name;

                    //讀取到cat元素 這時rdr.Read()讀取到的內容為<cat color="white">  
                    if (elementName == "action")
                    {
                        DiscoveryAction act = new DiscoveryAction();
                        //可以通過中括弧獲得屬性值  
                        act.Name = reader["name"];
                        act.UrlSrc = reader["urlsrc"];
                        act.Default = TransBool(reader["default"]);
                        act.Ext = reader["ext"];
                        act.ProGid = reader["progid"];
                        act.Requires = reader["requires"];
                        list.Add(act);
                    }
                }
            }
            return list;
        }
GetDiscovery

Discovery.xml文件下載:Disconvery

Controller Action代碼如下:

        [Route("files/{name}/links")]
        [HttpGetAttribute]
        public JsonResult GetOwaLinks(string name, string type, string access_token, string lang)
        {
            if (string.IsNullOrEmpty(type))
            {
                type = "view";
            }
            if (string.IsNullOrEmpty(lang))
            {
                lang = "zh-CN";
            }
            if (string.IsNullOrEmpty(access_token))
            {
                access_token = "H7lFBYT4pVMK";
            }
            List<string> lst = new List<string>();
            var res = XmlHelper.GetDiscoveryAction();
            var ext = Path.GetExtension(name).TrimStart('.');
            var discovery = res.Where(t => t.Ext == ext && t.Name == type);
            foreach (var item in discovery)
            {
                Console.WriteLine(item.UrlSrc);
                var index = item.UrlSrc.IndexOf('<');
                var api = System.Net.WebUtility.UrlEncode("http://localhost:5000/api/wopi/files/" + name);
                lst.Add(string.Format(item.UrlSrc.Substring(0, index) + "WOPISrc={0}&access_token={1}&ui={2}", api, access_token, lang));
            }
            return Json(lst);
        }
GetOwaLinks

測試訪問:http://localhost:5000/api/wopi/files/test.docx/links


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 自定義標題欄 一、設計界面樣式 <UserControl x:Class="WpfApplication6.TitleListControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="htt ...
  • WPF 自定義柱狀圖 當前的Telerik控制項、DevExpress控制項在圖表控制項方面做得不錯,但是有時項目中需要特定的樣式,不是只通過修改圖表的模板和樣式就能實現的。 或者說,通過修改當前的第三方控制項以達到項目中UI的界面效果,花費的時間遠比重新自定義一個控制項要長得多! 所以直接自定義柱狀圖吧~下 ...
  • 自定義雷達圖表如下: 1、創建UserControl,名為“RadarChartControl” 前臺: <UserControl x:Class="WpfApplication2.RadarChartControl" xmlns="http://schemas.microsoft.com/winf ...
  • http://www.cnblogs.com/bluestorm/p/3432190.html 問題:欄位初始值設定項無法引用非靜態欄位、方法或屬性的問題 下麵代碼出錯的原因,在類中定義的欄位為什麼不能用? public class Test {public Test(){}public int A ...
  • 1.定義基礎實體對象 2.定義業務實體對象 3.在DbContext類里重寫SaveChanges()方法 之所以選擇此方法,經過測試後最簡便方法。其他還有: 在OnSaveChanges(object obj, CollectionChangeEventArgs args)裡面去獲取實體狀態,根據 ...
  • 不同的xml文檔構可能要用到不同的方法進行解析這裡用到的是例如<student name="張三" id="1" sex="男"/>這樣的結構進行的解析 #region Xml文件常用操作 XmlDocument doc = new XmlDocument(); //創建文檔對象 doc.Load( ...
  • 什麼是觀察者模式? 摘自百度百科的說法:觀察者模式(有時又被稱為發佈(publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟體設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時 ...
  • 紋理映射非常實用,在游戲場景中已經無所不在了. 一個較少的多邊形構成的模形,配合好的紋理貼圖進行映射,可以得到逼真的效果.游戲中的天空,地面,牆面,和植物都是紋理貼圖進行映射的. 例如最終幻想8的男女主角多邊形數量是非常少的,完全靠貼圖保證真實效果。 以前的游戲中的樹木其實就是一個四邊形加上樹木貼圖 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...