در اولین پست وبلاگ، ما یک اپلیکیشن وب شبیه Google Docs ساختیم که دارای ویژگی‌های زیر است:

  • ویرایش متن غنی (تغییر فونت متن، اندازه، رنگ، سبک (پر رنگ، کج)، تراز و غیره).
  • ویرایش همزمان و همکاری در یک سند واحد. کاربران متعدد می‌توانند به سند در همان زمان دسترسی پیدا کرده و آن را تغییر دهند.
  • محتوای یک سند ورد موجود را به یک ویرایشگر بارگذاری کنید.

در این پست وبلاگ، ما برنامه وب خود را برای شامل ویژگی‌های زیر گسترش خواهیم داد:

  • محتوای ویرایشگر را به عنوان سند MS Word، PDF، TXT یا HTML دانلود کنید.
  • URL را با دوستان به اشتراک بگذارید تا بتوانند همزمان سند را ویرایش کنند.

محصول نهایی به شکل زیر خواهد بود:

رابط کاربری برنامه ای شبیه Google Docs

محتوای ویراستار را به عنوان سند مایکروسافت ورد دانلود کنید

نخست، ما یک عنصر <input> از نوع ارسال به فرم خود اضافه می‌کنیم تا دکمه “دانلود سند” را در رابط کاربری نمایش دهیم. ما از ویژگی asp-page-handler برای مشخص کردن هندلر دکمه استفاده می‌کنیم. عنصر فرم ما اکنون به صورت زیر به نظر می‌رسد:

<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" />
    <input type="submit" value="Download Document" class="btn btn-primary" asp-page-handler="DownloadDocument" />

    <input asp-for="DocumentContent" type="hidden" />
</form>

شما ممکن است متوجه شده‌اید که ما یک عنصر <input> دیگر از نوع hidden اضافه کرده‌ایم. این عنصر به ویژگی DocumentContent در Index.cshtml.cs متصل است. ما از این ویژگی برای ذخیره‌ی محتوای ویرایشگر به عنوان یک رشته HTML استفاده خواهیم کرد.

[BindProperty]
public string DocumentContent { get; set; }

Firepad یک رویداد دیگر برای گوش‌دادن را فراهم می‌کند. این رویداد زمانی فعال می‌شود که کلاینت محلی ما سند را ویرایش کند و زمانی که آن ویرایش‌ها با موفقیت به Firebase نوشته شده‌اند. ما یک callback به این نوع رویداد متصل می‌کنیم تا مقدار ویژگی DocumentContent را به firepad.getHtml() تنظیم کنیم. لطفاً کد زیر را به تابع init() در Index.cshtml اضافه کنید.

firepad.on('synced', function (isSynced) {
    // isSynced will be false immediately after the user edits 
    // the pad, and true when their edit has been saved to Firebase.
    if (isSynced) {
        document.getElementById("DocumentContent").value = firepad.getHtml();
    }
});

حالا ما عملکرد تابع OnPostDownloadDocument() را پیاده‌سازی می‌کنیم. ما از GroupDocs.Editor کتابخانه برای ذخیره محتوای ویرایشگر به‌عنوان سند مایکروسافت ورد استفاده می‌کنیم، که در ویژگی DocumentContent ذخیره شده است. این تابع سند ورد را به‌عنوان پاسخ به کاربر بازمی‌گرداند.

public FileResult OnPostDownloadDocument()
{
    // Editor object is referencing to the document initially uploaded for editing.
    WordProcessingLoadOptions loadOptions = new WordProcessingLoadOptions();
    Editor editor = new Editor(UploadedDocumentPath, delegate { return loadOptions; });
    
    // <html>, <head> and <body> tags are missing in the HTML string stored in DocumentContent, so we are adding them manually.
    string completeHTML = "<!DOCTYPE html><html><head><title></title></head><body>" + DocumentContent + "</body></html>";
    EditableDocument document = EditableDocument.FromMarkup(completeHTML, null);
    
    // Path to the output document        
    var projectRootPath = Path.Combine(_hostingEnvironment.ContentRootPath, "DownloadedDocuments");
    var outputPath = Path.Combine(projectRootPath, Path.GetFileName(UploadedDocumentPath));
    
    // Save the Word Document at the outputPath 
    WordProcessingSaveOptions saveOptions = new WordProcessingSaveOptions(WordProcessingFormats.Docx);
    editor.Save(document, outputPath, saveOptions);
    
    // Return the Word Document as response to the User
    var bytes = System.IO.File.ReadAllBytes(outputPath);        
    return new FileContentResult(bytes, new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.wordprocessingml.document"))
    {
        FileDownloadName = Path.GetFileName(UploadedDocumentPath)
    };
}

متغیر UploadedDocumentPath به عنوان یک رشته ناپایدار تعریف شده است تا مقدار مسیر سند بارگذاری شده بین جلسات حفظ شود.

static volatile string UploadedDocumentPath;

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

    // Retain the path of uploaded document between sessions.
    UploadedDocumentPath = filePath;

    ShowDocumentContentInTextEditor();
}

لطفاً مقالات Save Document و Create EditableDocument from file or markup را بررسی کنید تا بیشتر در مورد کلاس‌های GroupDocs.Editor بیاموزید.

پروژه را اجرا کنید و مورد استفاده زیر را آزمایش کنید:

  1. محتوای یک سند ورد موجود را با کلیک بر روی دکمه بارگذاری سند به ویرایشگر بارگذاری کنید.
  2. Make desired changes in the content.
  3. روی دکمه دانلود سند کلیک کنید تا محتوای به‌روز شده را به‌عنوان یک سند ورد دانلود کنید.

Download Content of the Editor as PDF Document

ما نیاز داریم چند تغییر در تابع OnPostDownloadDocument() ایجاد کنیم تا سند PDF را به عنوان پاسخ برگردانیم. ما از PdfSaveOptions به جای WordProcessingSaveOptions استفاده می کنیم و از application/pdf به عنوان نوع MIME استفاده می کنیم.

public FileResult OnPostDownloadDocument()
{
    WordProcessingLoadOptions loadOptions = new WordProcessingLoadOptions();
    Editor editor = new Editor(UploadedDocumentPath, delegate { return loadOptions; });

    string completeHTML = "<!DOCTYPE html><html><head><title></title></head><body>" + DocumentContent + "</body></html>";
    EditableDocument document = EditableDocument.FromMarkup(completeHTML, null);

    var projectRootPath = Path.Combine(_hostingEnvironment.ContentRootPath, "DownloadedDocuments");
    var outputPath = Path.Combine(projectRootPath, Path.GetFileNameWithoutExtension(UploadedDocumentPath) + ".pdf");

    PdfSaveOptions saveOptions = new PdfSaveOptions();
    editor.Save(document, outputPath, saveOptions);

    var bytes = System.IO.File.ReadAllBytes(outputPath);
    return new FileContentResult(bytes, new MediaTypeHeaderValue("application/pdf"))
    {
        FileDownloadName = Path.GetFileNameWithoutExtension(UploadedDocumentPath) + ".pdf"
    };
}

محتوای ویرایشگر را به عنوان سند متنی ساده دانلود کنید

برای بازگرداندن یک سند متنی ساده (.txt) به عنوان پاسخ، از کلاس TextSaveOptions استفاده می‌کنیم و از text/plain به عنوان نوع MIME استفاده می‌کنیم.

public FileResult OnPostDownloadDocument()
{
    WordProcessingLoadOptions loadOptions = new WordProcessingLoadOptions();
    Editor editor = new Editor(UploadedDocumentPath, delegate { return loadOptions; });

    string completeHTML = "<!DOCTYPE html><html><head><title></title></head><body>" + DocumentContent + "</body></html>";
    EditableDocument document = EditableDocument.FromMarkup(completeHTML, null);

    var projectRootPath = Path.Combine(_hostingEnvironment.ContentRootPath, "DownloadedDocuments");
    var outputPath = Path.Combine(projectRootPath, Path.GetFileNameWithoutExtension(UploadedDocumentPath) + ".txt");

    TextSaveOptions saveOptions = new TextSaveOptions();
    editor.Save(document, outputPath, saveOptions);

    var bytes = System.IO.File.ReadAllBytes(outputPath);
    return new FileContentResult(bytes, new MediaTypeHeaderValue("text/plain"))
    {
        FileDownloadName = Path.GetFileNameWithoutExtension(UploadedDocumentPath) + ".txt"
    };
}

Share URL of an Editor with friends

ما باید راهی راحت برای کاربران فراهم کنیم تا URL یک ویرایشگر را کپی کرده و با دوستان خود به اشتراک بگذارند. برای این کار، یک عنصر <input> از نوع متن را در Index.cshtml اضافه کنید.

<div>
    <strong>
        <label for="shareURL">Edit with Friends: </label>
    </strong>
    <input type="text" name="shareURL" id="shareURL" size="50">
</div>

مطمئن شوید که عنصر <div> فوق را قبل از تگ <div id="userlist"> اضافه کنید. ما مقدار این فیلد ورودی متنی را به URL یک ویرایشگر با استفاده از خط کد زیر تنظیم می‌کنیم. این کد را در تابع init() در Index.cshtml اضافه کنید.

document.getElementById("shareURL").value = window.location.origin + window.location.pathname + window.location.hash;

ما تغییرات جزئی در CSS خود اعمال خواهیم کرد تا اطمینان حاصل کنیم که فیلد ورودی متن به درستی نمایش داده می‌شود. موقعیت بالای فایرپد و فهرست کاربران را روی 100px تنظیم کنید و یک حاشیه چپ به فیلد ورودی متن اضافه کنید.

#userlist {
    position: absolute;
    left: 0;
    top: 100px;
    bottom: 0;
    height: auto;
    width: 175px;
}

#firepad {
    position: absolute;
    left: 175px;
    top: 100px;
    bottom: 0;
    right: 0;
    height: auto;
}

#uploadForm {
    margin: 16px 2px;
}

#shareURL {
    margin-left: 123px;
}

پروژه را اجرا کنید، باید یک فیلد متنی ببینید که به شما امکان می‌دهد URL ویرایشگر را کپی کنید. آن را با دوستان خود به اشتراک بگذارید و به‌طور همزمان با آن‌ها سند را ویرایش کنید.

کد منبع کامل پروژه در GitHub در دسترس است.

همچنین ببینید