اتصل بنا العديد من العملاء وسألونا عن كيفية إنشاء محرر مستندات Google مثل تطبيق الويب باستخدام واجهات برمجة التطبيقات الخاصة بنا. محرر مستندات Google هو معالج نصوص يتيح للمستخدمين إنشاء الملفات وتعديلها عبر الإنترنت أثناء التعاون مع مستخدمين آخرين في الوقت الفعلي.

يشرح منشور المدونة هذا مدى سهولة إنشاء إصدار خفيف من محرر مستندات Google يحتوي على الميزات التالية:

  • تحرير نص منسق (تغيير خط النص ، الحجم ، اللون ، النمط (بخط عريض ، مائل) ، المحاذاة وما إلى ذلك).
  • تحرير تعاوني في الوقت الحقيقي لنفس المستند. يمكن لعدة مستخدمين الوصول إلى المستند في نفس الوقت وتعديله.
  • تحميل محتوى مستند Word موجود إلى محرر.
  • احفظ النص في المحرر كمستند MS Word أو PDF أو TXT أو HTML.

سيبدو منتجنا النهائي على النحو التالي:

محرر مستندات Google مثل واجهة التطبيق

الأدوات والتقنيات - أنشئ مستندات Google مثل التطبيق

سنقوم بتطوير محرر مستندات Google مثل تطبيق الويب في ASP.NET Core واستخدام المكتبتين التاليتين:

  • Firepad هو محرر نصوص تعاوني مفتوح المصدر. يستخدم قاعدة بيانات Firebase Realtime كخلفية لذلك لا يتطلب أي رمز من جانب الخادم ويمكن إضافته إلى أي تطبيق ويب ببساطة عن طريق تضمين ملفات JavaScript.
  • GroupDocs.Editor for .NET يمنحنا القدرة على تحرير تنسيقات المستندات الأكثر شيوعًا باستخدام أي محرر WYSIWYG بدون أي تطبيقات إضافية. سنقوم بتحميل المستند عبر GroupDocs.Editor في Firepad ، ثم نقوم بتحرير المستند بالطريقة التي نريدها وحفظه مرة أخرى في تنسيق المستند الأصلي.

لقد استخدمت Visual Studio for Mac باعتباره IDE. ومع ذلك ، يمكنك تنزيل إصدار المجتمع المجاني من Visual Studio ، اعتمادًا على النظام الأساسي الخاص بك ، من هنا. لنبدأ.

قم بإنشاء مشروع ASP.NET Core Web Application جديد وقم بتسمية المشروع “GoogleDocsLite”.

قم بإنشاء تطبيق ويب ASP.NET Core جديد

قم بتشغيل التطبيق لضمان إعداد كل شيء بشكل صحيح.

دمج Firepad

يمكننا إضافة Firepad إلى تطبيق الويب الخاص بنا عن طريق تضمين ملفات JavaScript التالية في ملف قسم _Layout.cshtml.

<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-database.js"></script>

<!-- CodeMirror -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.css" />

<!-- Firepad -->
<link rel="stylesheet" href="https://firepad.io/releases/v1.5.9/firepad.css" />
<script src="https://firepad.io/releases/v1.5.9/firepad.min.js"></script>

<!-- userlist -->
<script src="~/js/firepad-userlist.js"></script>
<link rel="stylesheet" href="~/css/firepad-userlist.css" />

لإنشاء Firepad ، سنقوم بتهيئة Firebase و CodeMirror ثم Firepad. أضف البرنامج النصي التالي وتعليمات HTML البرمجية في Index.cshtml.

<script>
    function init() {
        // Initialize Firebase.
        // TODO: replace with your Firebase project configuration.
        var config = {
            apiKey: '',
            authDomain: "",
            databaseURL: ""
        };
        firebase.initializeApp(config);
        
        // Get Firebase Database reference.
        var firepadRef = getExampleRef();
        
        // Create CodeMirror (with lineWrapping on).
        var codeMirror = CodeMirror(document.getElementById('firepad'), { lineWrapping: true });

        // Create a random ID to use as our user ID (we must give this to firepad and FirepadUserList).
        var userId = Math.floor(Math.random() * 9999999999).toString();

        // Create Firepad (with rich text features and our desired userId).
        var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror,
                    { richTextToolbar: true, richTextShortcuts: true, userId: userId });

        // Create FirepadUserList (with our desired userId).
        var firepadUserList = FirepadUserList.fromDiv(firepadRef.child('users'),
        document.getElementById('userlist'), userId);
    }
    
    // Helper to get hash from end of URL or generate a random one.
    function getExampleRef() {
        var ref = firebase.database().ref();
        var hash = window.location.hash.replace(/#/g, '');
        if (hash) {
            ref = ref.child(hash);
        } else {
            ref = ref.push(); // generate unique location.
            window.location = window.location + '#' + ref.key; // add it as a hash to the URL.
        }
        if (typeof console !== 'undefined') {
            console.log('Firebase data: ', ref.toString());
        }
        return ref;
    }
</script>

<div id="userlist"></div>
<div id="firepad"></div>

يُرجى استبدال محتويات config بتكوين مشروع Firebase الخاص بك.

نريد تنفيذ البرنامج النصي أعلاه بمجرد تحميل صفحة الويب لجميع المحتوى بالكامل (ملفات البرامج النصية وملفات CSS وما إلى ذلك). لذلك ، استدعاء الدالة init() من سمة الحدث onLoad الخاصة بـ عنصر في _Layout.cshtml.

<body onload="init()">

الخاص بك يجب أن يبدو العنصر كما يلي. إذا كان يحتوي على علامات غير ضرورية مثل `` “،" “، يرجى إزالتها.

عنصر الجسم

إذا قمت بتشغيل المشروع ، فستلاحظ عدم محاذاة لوحة النار وقائمة المستخدمين بشكل صحيح. يرجى استخدام كود CSS التالي لضبط حجم / موضع لوحة الحماية وقائمة المستخدمين. يمكنك إضافة الكود التالي داخل عنصر Layout.cshtml.

<style>
    html {
        height: 100%;
    }

    body {
        margin: 0;
        height: 100%;
    }

    /* We make the user list 175px and firepad fill the rest of the page. */
    #userlist {
        position: absolute;
        left: 0;
        top: 50px;
        bottom: 0;
        height: auto;
        width: 175px;
    }

    #firepad {
        position: absolute;
        left: 175px;
        top: 50px;
        bottom: 0;
        right: 0;
        height: auto;
    }
</style>

تم إعداد Firepad بنجاح.

تحميل محتوى مستند Word موجود إلى محرر

نريد الآن أن نمنح مستخدمينا طريقة لتحميل محتوى مستند Word منتهي في محرر النصوص. على الواجهة الأمامية ، نضيف ملف عنصر من نوع ملف يتيح للمستخدم تحديد مستند Word من جهازه المحلي. في الخلفية ، نستخدم مكتبة GroupDocs.Editor لاسترداد محتوى مستند Word كسلسلة HTML. أخيرًا ، نستخدم طريقة setHtml () الخاصة بـ Firepad لإظهار المحتوى في محرر النصوص.

أضف ما يلي عنصر في ملف Index.cshtml من قبل بطاقة شعار.

<form method="post" enctype="multipart/form-data" id="uploadForm">
    <input asp-for="UploadedDocument" />
    <input type="submit" value="Upload Document" class="btn btn-primary" asp-page-handler="UploadDocument" />
</form>

في ملف Index.cshtml.cs ، حدد خاصية مقابلة.

[BindProperty]
public IFormFile UploadedDocument { get;  set; }

قم بتشغيل المشروع وانقر على زر اختيار الملف. حدد مستند Word الذي تريد تحميله وانقر على زر تحميل المستند. لن يحدث شيء لأننا لم نحدد المعالج في Index.cshtml.cs بعد. قبل أن نقوم بذلك ، دعنا أولاً نضيف مكتبة GroupDocs.Editor في مشروعنا.

دمج GroupDocs.Editor

GroupDocs.Editor متاح كحزمة NuGet حتى نتمكن من إضافته بسهولة إلى مشروعنا. انقر بزر الماوس الأيمن فوق المشروع وحدد خيار إدارة حزم NuGet. ستفتح نافذة إدارة حزم NuGet ، وحدد علامة التبويب استعراض ، وأدخل GroupDocs.Editor في حقل البحث. يجب أن يظهر GroupDocs.Editor كنتيجة أولى ، حدده ثم انقر فوق الزر “إضافة حزمة”.

أضف GroupDocs.Editor عبر NuGet Package Manager

عند إضافة الحزمة بنجاح ، ستظهر ضمن المجلد الفرعي NuGet في مجلد التبعيات.

معالجة بيانات النموذج

نكتب الآن معالجًا (طريقة OnPostUploadDocument ()) سيتم استدعاؤه عندما ينقر المستخدم على زر تحميل المستند. يحتوي كائن UploadedDocument (من نوع IFormFile) على محتوى المستند الذي تم تحميله. أولاً ، نحفظ المستند على الخادم ثم نستخدم مكتبة GroupDocs.Editor للحصول على محتواها كسلسلة HTML. الرجاء إضافة الكود التالي في ملف Index.cshtml.cs.

private readonly IWebHostEnvironment _hostingEnvironment;

public string DocumentContent { get; set; }

public IndexModel(IWebHostEnvironment hostingEnvironment)
{
    _hostingEnvironment = hostingEnvironment;
}

public void OnPostUploadDocument()
{
    var projectRootPath = Path.Combine(_hostingEnvironment.ContentRootPath, "UploadedDocuments");
    var filePath = Path.Combine(projectRootPath, UploadedDocument.FileName);
    UploadedDocument.CopyTo(new FileStream(filePath, FileMode.Create));
    ShowDocumentContentInTextEditor(filePath);
}

private void ShowDocumentContentInTextEditor(string filePath)
{
    WordProcessingLoadOptions loadOptions = new WordProcessingLoadOptions();
    Editor editor = new Editor(filePath, delegate { return loadOptions; }); //passing path and load options (via delegate) to the constructor
    EditableDocument document = editor.Edit(new WordProcessingEditOptions()); //opening document for editing with format-specific edit options

    DocumentContent = document.GetContent();
}

يوفر Firepad حدثين للاستماع. واحد منهم “جاهز” والذي يتم إطلاقه بمجرد أن يقوم Firepad باسترداد محتويات المحرر الأولي. نقوم بإرفاق رد اتصال بهذا النوع من الأحداث وفي رد الاتصال ، نقوم بتمرير سلسلة DocumentContent كوسيطة لطريقة setHtml () لكائن firepad. الرجاء إضافة الكود التالي في دالة init () في Index.cshtml.

firepad.on('ready', function () {
    if (firepad.isHistoryEmpty()) {
        var documentContent = '@Model.DocumentContent';
        if (documentContent.length != 0) {   
            firepad.setHtml(htmlDecode(documentContent));
        } else {
            firepad.setText("Welcome to your own private pad! Share the URL above and collaborate with your friends.");
        }
    }
});

ربما لاحظت أننا مررنا سلسلة documentContent أولاً إلى طريقة htmlDecode () قبل التمرير إلى طريقة setHtml (). هو استبدال كيانات الأحرف مثل <،> بعلامات (< و >). تبدو طريقة htmlDecode () على النحو التالي.

function htmlDecode(input) {
    var e = document.createElement('div');
    e.innerHTML = input;
    return e.childNodes[0].nodeValue;
}

قم بتشغيل المشروع ، الآن يجب أن تكون قادرًا على تحميل محتوى مستند Word إلى محرر.

في الجزء الثاني من هذا المنشور ، شرحت كيف يمكننا توسيع تطبيقنا ليشمل الميزات التالية:

  • قم بتنزيل محتوى المحرر كمستند MS Word أو PDF أو TXT أو HTML.
  • شارك عنوان URL مع الأصدقاء حتى يتمكنوا من تحرير المستند في نفس الوقت.

من فضلك تحقق من ذلك.

كود المصدر الكامل للمشروع متاح على GitHub.

أنظر أيضا