如何使用带有专有java后端文档系统的MS Office

2024-03-04

目前我有一个文档系统,可以在 iframe 中启动 Star Office 或 LibreOffice 中的文档。

展望未来,我理想地希望保留现有的文档系统,但将其集成到 SharePoint 中,以便我们能够使用 MS Office 打开和编辑文档。

由于没有 Java Api 可以与 MS Office 集成,这就是我选择使用 SharePoint 的原因。

我可以设法从共享点页面上的链接加载我的文档,但接下来的困难部分是操作 MS Office 中的保存功能并确保我的文档不会保存在共享点中。

有没有人做过类似的事情。

基本上我只想使用 MS Office 与我的文档进行交互,而不将内容存储在共享点中。所以我需要访问保存功能等。

据我所知,Apache POI 不是一个可行的解决方案,因为它不会物理打开文档并允许用户单击文件 -> 保存。我的理解是它可以通过在代码中操作文档来操作文档,但不能使用office中的任何控件。

我读过这里您可以重新调整 Office 中的命令并修改功能区吗?

感谢您的任何建议

WOPI 和 Office Web Apps 似乎可以实现这一点。基本上需要创建一个 WOPI 应用程序


好吧,我也遇到了同样的问题,所以我实际上用 Apache POI 和 SVG 编辑编写了一个快速 PPT 编辑器。但后来我切换到 Office Web Apps。这是 WOPI 服务器的快速实现,我是一个 Java 人员,所以我的.NET 技能非常糟糕。编写 servlet 应该很简单。

逻辑很简单:

将 WOPISrc 传递到 Office Web 应用程序 - 这基本上是 WOPI 服务器的 URL,其中包含文件位置。您现在可以忽略 access_token/access_token_ttl 。

Office Web Apps 至少有 2 个请求命中 WOPISrc url:

  1. 这将是一个元数据请求,基本上是对 WOPIsrc 的 GET 调用。您将创建一个 WOPI (CheckFileInfo) 对象并将其以 JSON 编码发送回 Office Web 应用程序。
  2. 现在,Office Web Apps 将请求文件本身,它将附加 ( /contents ) 到 WOPIsrc 的末尾。所以只需以二进制格式发送回来即可。
  3. (可选)Office Web Apps 将在保存时向 (WOPISrc +“/contents”) 执行 POST。您可以从 POST 中获取数据并将其保存到磁盘。

注意:Word 不起作用:/ 您只能查看,要进行编辑,您需要实现 Cobalt 协议 (FSSHTTP)。我正在研究这个主题,但用 C# 编写会更容易,因为你可以获取 Cobalt 程序集。否则,该协议使用 BASE64 编码的二进制消息 (FSSHTTPB) 实现 SOAP (FSSHTTP)

使用如下命令打开 Office Web Apps:

http://OFFICEWEBAPPS.HOST/p/PowerPointFrame.aspx?PowerPointView=EditView&access_token=12345&WOPISrc=URLENCODED_URL_OF_THE_WOPI_SERVER

Like: http://WOPISERVER.HOST:2000/wopi/files/1.pptx

这将在您的 c:\temp 中打开 1.pptx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.Serialization;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.IO;
using System.Runtime.Serialization.Json;

namespace WopiServerTutorial
{
    public class WopiServer
    {
        private HttpListener Listener;

        static void Main(string[] args)
        {
            WopiServer s = new WopiServer();
            s.Start();

            Console.WriteLine("A simple wopi webserver. Press a key to quit.");
            Console.ReadKey();

            s.Stop();
        }

        public void Start()
        {
            Listener = new HttpListener();
            Listener.Prefixes.Add(@"http://+:8080/");
            Listener.Start();
            Listener.BeginGetContext(ProcessRequest, Listener);
            Console.WriteLine(@"WopiServer Started");
        }

        public void Stop()
        {
            Listener.Stop();
        }

        private void ProcessRequest(IAsyncResult result)
        {
            HttpListener listener = (HttpListener)result.AsyncState;
            HttpListenerContext context = listener.EndGetContext(result);

            Console.WriteLine(@"Got a " + context.Request.HttpMethod  + " request for URL: " + context.Request.Url.PathAndQuery);
            var stringarr = context.Request.Url.AbsolutePath.Split('/');
            var rootDir = @"C:\\temp\\";

            if (stringarr.Length == 5 && context.Request.HttpMethod.Equals(@"GET"))
            {
                Console.WriteLine(@"Getting content for the file: " + rootDir + stringarr[3]);

                // get file's content
                var file = rootDir + stringarr[3];
                var stream = new FileStream(file, FileMode.Open);
                var fi = new FileInfo(file);

                context.Response.ContentType = @"application/octet-stream";
                context.Response.ContentLength64 = fi.Length;
                stream.CopyTo(context.Response.OutputStream);
                context.Response.Close();
            }
            //else if (stringarr.Length == 5 && context.Request.HttpMethod.Equals(@"POST"))
            //{
            //    // write
            //}
            else if (stringarr.Length == 4 && context.Request.HttpMethod.Equals(@"GET"))
            {
                Console.WriteLine(@"Getting metdata for the file: " + rootDir + stringarr[3]);
                var fi = new FileInfo(rootDir + stringarr[3]);

                CheckFileInfo cfi = new CheckFileInfo();
                cfi.AllowExternalMarketplace = false;
                cfi.BaseFileName = fi.Name;
                cfi.BreadcrumbBrandName = "";
                cfi.BreadcrumbBrandUrl = "";
                cfi.BreadcrumbDocName = "";
                cfi.BreadcrumbDocUrl = "";
                cfi.BreadcrumbFolderName = "";
                cfi.BreadcrumbFolderUrl = "";
                cfi.ClientUrl = "";
                cfi.CloseButtonClosesWindow = false;
                cfi.CloseUrl = "";
                cfi.DisableBrowserCachingOfUserContent = true;
                cfi.DisablePrint = true;
                cfi.DisableTranslation = true;
                cfi.DownloadUrl = "";
                cfi.FileUrl = "";
                cfi.FileSharingUrl = "";
                cfi.HostAuthenticationId = "s-1-5-21-3430578067-4192788304-1690859819-21774";
                cfi.HostEditUrl = "";
                cfi.HostEmbeddedEditUrl = "";
                cfi.HostEmbeddedViewUrl = "";
                cfi.HostName = @"SharePoint";
                cfi.HostNotes = @"HostBIEnabled";
                cfi.HostRestUrl = "";
                cfi.HostViewUrl = "";
                cfi.IrmPolicyDescription = "";
                cfi.IrmPolicyTitle = "";
                cfi.OwnerId = @"4257508bfe174aa28b461536d8b6b648";
                cfi.PresenceProvider = "AD";
                cfi.PresenceUserId = @"S-1-5-21-3430578067-4192788304-1690859819-21774";
                cfi.PrivacyUrl = "";
                cfi.ProtectInClient = false;
                cfi.ReadOnly = false;
                cfi.RestrictedWebViewOnly = false;
                cfi.SHA256 = "";
                cfi.SignoutUrl = "";
                cfi.Size = fi.Length;
                cfi.SupportsCoauth = false;
                cfi.SupportsCobalt = false;
                cfi.SupportsFolders = false;
                cfi.SupportsLocks = true;
                cfi.SupportsScenarioLinks = false;
                cfi.SupportsSecureStore = false;
                cfi.SupportsUpdate = true;
                cfi.TenantId = @"33b62539-8c5e-423c-aa3e-cc2a9fd796f2";
                cfi.TermsOfUseUrl = "";
                cfi.TimeZone = @"+0300#0000-11-00-01T02:00:00:0000#+0000#0000-03-00-02T02:00:00:0000#-0060";
                cfi.UserCanAttend = false;
                cfi.UserCanNotWriteRelative = false;
                cfi.UserCanPresent = false;
                cfi.UserCanWrite = true;
                cfi.UserFriendlyName = "";
                cfi.UserId = "";
                cfi.Version = @"%22%7B59CCD75F%2D0687%2D4F86%2DBBCF%2D059126640640%7D%2C1%22";
                cfi.WebEditingDisabled = false;

                // encode json
                var memoryStream = new MemoryStream();
                var json = new DataContractJsonSerializer(typeof(CheckFileInfo));
                json.WriteObject(memoryStream, cfi);
                memoryStream.Flush();
                memoryStream.Position = 0;
                StreamReader streamReader = new StreamReader(memoryStream);
                var jsonResponse = Encoding.UTF8.GetBytes(streamReader.ReadToEnd());

                context.Response.ContentType = @"application/json";
                context.Response.ContentLength64 = jsonResponse.Length;
                context.Response.OutputStream.Write(jsonResponse, 0, jsonResponse.Length);
                context.Response.Close();
            }
            else
            {
                byte[] buffer = Encoding.UTF8.GetBytes("");
                context.Response.ContentLength64 = buffer.Length;
                context.Response.ContentType = @"application/json";
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                context.Response.OutputStream.Close();
            }

            Listener.BeginGetContext(ProcessRequest, Listener);
        }
    }

    [DataContract]
    public class CheckFileInfo
    {
        [DataMember]
        public bool AllowExternalMarketplace { get; set; }
        [DataMember]
        public string BaseFileName { get; set; }
        [DataMember]
        public string BreadcrumbBrandName { get; set; }
        [DataMember]
        public string BreadcrumbBrandUrl { get; set; }
        [DataMember]
        public string BreadcrumbDocName { get; set; }
        [DataMember]
        public string BreadcrumbDocUrl { get; set; }
        [DataMember]
        public string BreadcrumbFolderName { get; set; }
        [DataMember]
        public string BreadcrumbFolderUrl { get; set; }
        [DataMember]
        public string ClientUrl { get; set; }
        [DataMember]
        public bool CloseButtonClosesWindow { get; set; }
        [DataMember]
        public string CloseUrl { get; set; }
        [DataMember]
        public bool DisableBrowserCachingOfUserContent { get; set; }
        [DataMember]
        public bool DisablePrint { get; set; }
        [DataMember]
        public bool DisableTranslation { get; set; }
        [DataMember]
        public string DownloadUrl { get; set; }
        [DataMember]
        public string FileSharingUrl { get; set; }
        [DataMember]
        public string FileUrl { get; set; }
        [DataMember]
        public string HostAuthenticationId { get; set; }
        [DataMember]
        public string HostEditUrl { get; set; }
        [DataMember]
        public string HostEmbeddedEditUrl { get; set; }
        [DataMember]
        public string HostEmbeddedViewUrl { get; set; }
        [DataMember]
        public string HostName { get; set; }
        [DataMember]
        public string HostNotes { get; set; }
        [DataMember]
        public string HostRestUrl { get; set; }
        [DataMember]
        public string HostViewUrl { get; set; }
        [DataMember]
        public string IrmPolicyDescription { get; set; }
        [DataMember]
        public string IrmPolicyTitle { get; set; }
        [DataMember]
        public string OwnerId { get; set; }
        [DataMember]
        public string PresenceProvider { get; set; }
        [DataMember]
        public string PresenceUserId { get; set; }
        [DataMember]
        public string PrivacyUrl { get; set; }
        [DataMember]
        public bool ProtectInClient { get; set; }
        [DataMember]
        public bool ReadOnly { get; set; }
        [DataMember]
        public bool RestrictedWebViewOnly { get; set; }
        [DataMember]
        public string SHA256 { get; set; }
        [DataMember]
        public string SignoutUrl { get; set; }
        [DataMember]
        public long Size { get; set; }
        [DataMember]
        public bool SupportsCoauth { get; set; }
        [DataMember]
        public bool SupportsCobalt { get; set; }
        [DataMember]
        public bool SupportsFolders { get; set; }
        [DataMember]
        public bool SupportsLocks { get; set; }
        [DataMember]
        public bool SupportsScenarioLinks { get; set; }
        [DataMember]
        public bool SupportsSecureStore { get; set; }
        [DataMember]
        public bool SupportsUpdate { get; set; }
        [DataMember]
        public string TenantId { get; set; }
        [DataMember]
        public string TermsOfUseUrl { get; set; }
        [DataMember]
        public string TimeZone { get; set; }
        [DataMember]
        public bool UserCanAttend { get; set; }
        [DataMember]
        public bool UserCanNotWriteRelative { get; set; }
        [DataMember]
        public bool UserCanPresent { get; set; }
        [DataMember]
        public bool UserCanWrite { get; set; }
        [DataMember]
        public string UserFriendlyName { get; set; }
        [DataMember]
        public string UserId { get; set; }
        [DataMember]
        public string Version { get; set; }
        [DataMember]
        public bool WebEditingDisabled { get; set; }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用带有专有java后端文档系统的MS Office 的相关文章

  • 从 Android 函数更新 Textview

    有人可以告诉我如何从函数更新 Android Textview 控件吗 我在互联网上进行了深入搜索 看到很多人都问同样的问题 我测试了线程但无法工作 有人有一个简单的工作示例吗 例如 调用一个函数 在循环中运行多次 并且该函数在 TextV
  • java 拖放

    我尝试熟悉java中的拖放 但我发现的所有教程都是 让我生气 我想要的只是从 JList 包含在名为 UserPanel 的自制 JPanel 中 拖动 PublicUserLabel 并将其放入从 JTabbedPanel 继承的自制类中
  • openFileOutput 在单例类中无法正常工作 - 想法/解决方法?

    作为一名 Android 开发新手 我遇到了一些奇怪的问题 我想创建一个类 它方法其他类 活动 任何可以用于以某种特殊方式处理文件的类 假设为了简单起见 我们将记录一些内容 如果我在活动中执行以下操作 例如在 OnClick 侦听器中 则一
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • 如何杀死 Java Future?

    我正在开发的服务使用 Future 来并行运行多个任务 每个任务最多可能需要一分钟才能完成 然而 外部库似乎有问题 因为在某些情况下 2 的时间 它不会返回 在这些情况下 我想给出 2 分钟的等待时间 如果还没有返回 我想杀死 future
  • Spring 从 JBoss 上下文加载 PropertySourcesPlaceholderConfigurer

    我有一个使用 PropertySourcesPlaceholderConfigurer 的 spring 3 1 应用程序加载设置 我想管理测试和生产环境 只需从服务器上下文加载设置覆盖本地文件属性中指定的设置 下一个示例在 Tomcat
  • 是否可以使用 Apache Tika 提取表信息?

    我正在寻找 pdf 和 MS Office 文档格式的解析器 以从文件中提取表格信息 当我看到 Apache Tika 时 正在考虑编写单独的实现 我能够从任何这些文件格式中提取全文 但我的要求是提取表格数据 我希望有 2 列采用键值格式
  • 递归取消 allOf CompletableFuture

    如果我有 CompletableFuture
  • 我的 Kafka 流应用程序刚刚退出,代码为 0,什么也不做

    为了尝试 Kafka 流 我这样做了 public static void main String args final StreamsBuilder builder new StreamsBuilder final Properties
  • 在约束验证器中使用 Guice 进行依赖注入

    我有一个在 ConstraintValidator 的实现中注入类的用例 我正在使用 Google guice 进行依赖项注入 目前无法在验证器内注入 我的场景的简化形式 内部模块 Provides Singleton public Ser
  • Hybris:如何在impex中导入zip文件中的媒体?

    我知道我们可以导入未像这样压缩的图像 siteResource jar com project initialdata constants ProjectInitialDataConstants projectinitialdata imp
  • 向Java类库添加函数

    我使用的 Java 类库在很多方面都不完整 有很多类我认为应该内置其他成员函数 但是 我不确定添加这些成员函数的最佳实践 让我们调用不足的基类A class A public A long arbitrary arguments publi
  • 如何在一次操作中使用 Thymeleaf 检查 null 和空条件?

    有什么方法可以检查 Thymeleaf 中的 null 和empty 条件吗 方法一 1 variable1 variable2 variable3 2 variable null 3 variable 如果我们结合两个条件 例如 vari
  • 在 Tensorflow-lite Android 中将位图转换为 ByteBuffer(浮点)

    在用于图像分类的tensorflow lite android演示代码中 图像首先转换为ByteBuffer格式以获得更好的性能 这种从位图到浮点格式的转换以及随后到字节缓冲区的转换似乎是一个昂贵的操作 循环 按位运算符 float mem
  • 在 Spring MVC 中将请求写入文件

    我希望能够将整个请求写入 Spring MVC 控制器中的文件 我已尝试以下操作 但即使我使用大量参数发出 POST 请求 文件也始终为空 RequestMapping method RequestMethod POST value pay
  • 难以理解 通配符

    我有一个非常基本的问题 下面的代码无法编译 假设 Apple Extends Fruit List
  • 如何在不使用 -cp 开关的情况下在 Groovy 中自动加载数据库 jar?

    我想简化调用 Oracle 数据库的 Groovy 脚本的执行 如何将 ojdbc jar 添加到默认类路径以便我可以运行 groovy RunScript groovy 代替 groovy cp ojdbc5 jar RunScript
  • 用于生成 ISO 文件的 Maven 插件

    有没有可以生成ISO镜像的maven插件 我需要获取一些模块的输出 主要是包含 jar 的 zip 文件 并将它们组合成一个 ISO 映像 Thanks 现在有一个 ISO9660 maven 插件可以完成这项工作 https github
  • MyBatis 枚举的使用

    我知道以前有人问过这个问题 但我无法根据迄今为止找到的信息实施解决方案 所以也许有人可以向我解释一下 我有一个表 状态 它有两列 id 和 name id是PK 我不想使用 POJO Status 而是使用枚举 我创建了这样一个枚举 如下所

随机推荐