javascript - 有没有办法可以使用 CKEditor 随时随地修改 MS Word 文档并将其保存在我的服务器中的某个位置

标签 javascript c# ms-word ckeditor

我的要求是制作一个自定义文档库,我可以在其中保存带有版本的文档。

有没有办法可以使用 CKEditor 随时随地修改 MS Word 文档(.doc 或 .docx)并将其保存在我的服务器中的某个位置?

有关任何其他选项的建议也是可以接受的。

最佳答案

我不确定 .doc,但对于 .docx,您可以通过以下方式将其转换为 html...

您应该为此实现 OpenXml dll。 您需要的 dll 是

<强>1。 DocumentFormat.OpenXml.dll

<强>2。 OpenXmlPowerTools.dll

<强>3。 System.IO.Packaging.dll

这是代码片段的工作版本。 DocxToHtml.cs

    using System.IO;
    using System.Linq;
    using OpenXmlPowerTools;
    using DocumentFormat.OpenXml.Packaging;
    using System.Drawing.Imaging;
    using System.Xml.Linq;

     public class DocxToHtml
{

    public string ConvertToHtml(string fullFilePath)
    {
        if (string.IsNullOrEmpty(fullFilePath) || Path.GetExtension(fullFilePath) != ".docx")
            return "Unsupported format";

        FileInfo fileInfo = new FileInfo(fullFilePath);

        string htmlText = string.Empty;
        try
        {
            htmlText = ParseDOCX(fileInfo);
        }
        catch (OpenXmlPackageException e)
        {

            if (e.ToString().Contains("Invalid Hyperlink"))
            {
                using (FileStream fs = new FileStream(fullFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    UriFixer.FixInvalidUri(fs, brokenUri => FixUri(brokenUri));
                }
                htmlText = ParseDOCX(fileInfo);
            }
        }


        return htmlText;


    }

    private static string FixUri(string brokenUri)
    {
        string newURI = string.Empty;

        if (brokenUri.Contains("mailto:"))
        {
            int mailToCount = "mailto:".Length;
            brokenUri = brokenUri.Remove(0, mailToCount);
            newURI = brokenUri;
        }
        else
        {
            newURI = " ";
        }
        return newURI;
    }


    private string ParseDOCX(FileInfo fileInfo)
    {
        byte[] byteArray = File.ReadAllBytes(fileInfo.FullName);
        using (MemoryStream memoryStream = new MemoryStream())
        {
            memoryStream.Write(byteArray, 0, byteArray.Length);


            using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true))
            {

                int imageCounter = 0;

                var pageTitle = fileInfo.FullName;
                var part = wDoc.CoreFilePropertiesPart;
                if (part != null)
                    pageTitle = (string)part.GetXDocument().Descendants(DC.title).FirstOrDefault() ?? fileInfo.FullName;

                // TODO: Determine max-width from size of content area.
                WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings()
                {
                    AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
                    PageTitle = pageTitle,
                    FabricateCssClasses = true,
                    CssClassPrefix = "pt-",
                    RestrictToSupportedLanguages = false,
                    RestrictToSupportedNumberingFormats = false,
                    ImageHandler = imageInfo =>
                    {
                        ++imageCounter;
                        string extension = imageInfo.ContentType.Split('/')[1].ToLower();
                        ImageFormat imageFormat = null;
                        if (extension == "png")
                            imageFormat = ImageFormat.Png;
                        else if (extension == "gif")
                            imageFormat = ImageFormat.Gif;
                        else if (extension == "bmp")
                            imageFormat = ImageFormat.Bmp;
                        else if (extension == "jpeg")
                            imageFormat = ImageFormat.Jpeg;
                        else if (extension == "tiff")
                        {
                            // Convert tiff to gif.
                            extension = "gif";
                            imageFormat = ImageFormat.Gif;
                        }
                        else if (extension == "x-wmf")
                        {
                            extension = "wmf";
                            imageFormat = ImageFormat.Wmf;
                        }

                        // If the image format isn't one that we expect, ignore it,
                        // and don't return markup for the link.
                        if (imageFormat == null)
                            return null;

                        string base64 = null;
                        try
                        {
                            using (MemoryStream ms = new MemoryStream())
                            {
                                imageInfo.Bitmap.Save(ms, imageFormat);
                                var ba = ms.ToArray();
                                base64 = System.Convert.ToBase64String(ba);
                            }
                        }
                        catch (System.Runtime.InteropServices.ExternalException)
                        { return null; }


                        ImageFormat format = imageInfo.Bitmap.RawFormat;
                        ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == format.Guid);
                        string mimeType = codec.MimeType;

                        string imageSource = string.Format("data:{0};base64,{1}", mimeType, base64);

                        XElement img = new XElement(Xhtml.img,
                            new XAttribute(NoNamespace.src, imageSource),
                            imageInfo.ImgStyleAttribute,
                            imageInfo.AltText != null ?
                                new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
                        return img;
                    }
                };

                XElement htmlElement = WmlToHtmlConverter.ConvertToHtml(wDoc, settings);

                var html = new XDocument(new XDocumentType("html", null, null, null), htmlElement);
                var htmlString = html.ToString(SaveOptions.DisableFormatting);
                return htmlString;

            }
        }
    }


}

这是上面代码使用的Uri修复程序类

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

public static class UriFixer
{
    public static void FixInvalidUri(Stream fs, Func<string, string> invalidUriHandler)
    {
        XNamespace relNs = "http://schemas.openxmlformats.org/package/2006/relationships";
        using (ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Update))
        {
            foreach (var entry in za.Entries.ToList())
            {
                if (!entry.Name.EndsWith(".rels"))
                    continue;
                bool replaceEntry = false;
                XDocument entryXDoc = null;
                using (var entryStream = entry.Open())
                {
                    try
                    {
                        entryXDoc = XDocument.Load(entryStream);
                        if (entryXDoc.Root != null && entryXDoc.Root.Name.Namespace == relNs)
                        {
                            var urisToCheck = entryXDoc
                                .Descendants(relNs + "Relationship")
                                .Where(r => r.Attribute("TargetMode") != null && (string)r.Attribute("TargetMode") == "External");
                            foreach (var rel in urisToCheck)
                            {
                                var target = (string)rel.Attribute("Target");
                                if (target != null)
                                {
                                    try
                                    {
                                        Uri uri = new Uri(target);
                                    }
                                    catch (UriFormatException)
                                    {
                                        string newUri = invalidUriHandler(target);
                                        rel.Attribute("Target").Value = newUri;
                                        replaceEntry = true;
                                    }
                                }
                            }
                        }
                    }
                    catch (XmlException)
                    {
                        continue;
                    }
                }
                if (replaceEntry)
                {
                    var fullName = entry.FullName;
                    entry.Delete();
                    var newEntry = za.CreateEntry(fullName);
                    using (StreamWriter writer = new StreamWriter(newEntry.Open()))
                    using (XmlWriter xmlWriter = XmlWriter.Create(writer))
                    {
                        entryXDoc.WriteTo(xmlWriter);
                    }
                }
            }
        }
    }


}

您所要做的就是向 ConvertToHtml 方法提供 .docx 文件的文件路径,它将为您完成工作并为您提供 html。

注意:这只支持.docx

关于javascript - 有没有办法可以使用 CKEditor 随时随地修改 MS Word 文档并将其保存在我的服务器中的某个位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41219860/

相关文章:

vba - Word VBA 应用程序.退出问题

javascript - 类型错误 : Cannot read property 'style' of undefined NodeJS

javascript - 缩小一个 DIV 和所有子元素

c# - 浮点加法 : loss-of-precision issues

c# - 识别 Facebook 域模型中的实体和值对象

c# - 移植到 HTML 时来自 MSWord 的 WMZ 文件

javascript - DOM 中报告的奇怪宽度(0,当元素有宽度时)

javascript - 当a是数组时,: t = a and t = [. ..a]有什么区别?

c# - 如何为动态加载的 native dll 调整 %PATH%?

javascript - 使用 Office 插件更改 MS Word 中的主菜单