Trong bài đăng blog đầu tiên, chúng tôi đã tạo một ứng dụng web giống như Google Tài liệu có các tính năng sau:

  • Chỉnh sửa văn bản đa dạng thức (thay đổi phông chữ, kích thước, màu sắc, kiểu văn bản (in đậm, in nghiêng), căn chỉnh, v.v.).
  • Chỉnh sửa cộng tác theo thời gian thực của cùng một tài liệu. Nhiều người dùng có thể truy cập tài liệu cùng một lúc và sửa đổi nó.
  • Tải nội dung của Tài liệu Word hiện có lên trình chỉnh sửa.

Trong bài đăng trên blog này, chúng tôi sẽ mở rộng ứng dụng web của mình để bao gồm các tính năng sau:

  • Tải xuống nội dung của trình chỉnh sửa dưới dạng tài liệu MS Word, PDF, TXT hoặc HTML.
  • Chia sẻ URL với bạn bè để họ có thể chỉnh sửa tài liệu cùng lúc.

Sản phẩm cuối cùng sẽ trông như sau:

Google Documents giống như Giao diện ứng dụng

Tải xuống nội dung của Editor dưới dạng tài liệu Microsoft Word

Đầu tiên, chúng ta thêm một <input> phần tử thuộc loại gửi tới biểu mẫu của chúng tôi để hiển thị nút “Tải xuống tài liệu" ở giao diện người dùng. Chúng tôi sử dụng thuộc tính asp-page-handler để chỉ định trình xử lý nút. Phần tử biểu mẫu của chúng tôi bây giờ trông như sau:

<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>

Bạn có thể nhận thấy rằng chúng tôi đã thêm một cái khác <input> phần tử thuộc loại bị ẩn. Phần tử này được liên kết với thuộc tính DocumentContent trong Index.cshtml.cs. Chúng tôi sẽ sử dụng thuộc tính này để lưu trữ nội dung của trình soạn thảo dưới dạng chuỗi HTML.

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

Firepad cung cấp một sự kiện khác được đồng bộ hóa để nghe. Nó được kích hoạt khi khách hàng địa phương của chúng tôi chỉnh sửa tài liệu và khi những chỉnh sửa đó được ghi thành công vào Firebase. Chúng tôi đính kèm lệnh gọi lại vào loại sự kiện này để đặt giá trị của thuộc tính DocumentContent thành firepad.getHtml(). Vui lòng thêm đoạn mã sau vào hàm init() trong 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();
    }
});

Bây giờ chúng tôi triển khai chức năng của trình xử lý OnPostDownloadDocument(). Chúng tôi sử dụng thư viện GroupDocs.Editor để lưu nội dung của trình chỉnh sửa dưới dạng tài liệu Microsoft Word, được lưu trữ trong thuộc tính DocumentContent. Trình xử lý trả về tài liệu Word dưới dạng phản hồi cho người dùng.

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)
    };
}

Biến UploadDocumentPath được định nghĩa là một chuỗi dễ thay đổi để giữ giá trị của đường dẫn tài liệu được tải lên giữa các phiên.

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();
}

Vui lòng xem các bài viết Lưu tài liệuTạo tài liệu có thể chỉnh sửa từ tệp hoặc đánh dấu để tìm hiểu thêm về các lớp GroupDocs.Editor.

Chạy dự án và kiểm tra trường hợp sử dụng sau:

  1. Tải nội dung của tài liệu Word hiện có lên trình chỉnh sửa bằng cách nhấp vào nút Tải tài liệu lên.
  2. Thực hiện những thay đổi mong muốn trong nội dung.
  3. Nhấn vào nút Download Document để tải nội dung cập nhật dưới dạng Word Document.

Tải xuống nội dung của Trình chỉnh sửa dưới dạng tài liệu PDF

Chúng ta cần thực hiện một số sửa đổi trong trình xử lý OnPostDownloadDocument() để trả về tài liệu PDF dưới dạng phản hồi. Chúng tôi sử dụng PdfSaveOptions thay vì WordProcessingSaveOptions và sử dụng application/pdf làm loại 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"
    };
}

Tải xuống nội dung của Trình chỉnh sửa dưới dạng tài liệu văn bản thuần túy

Để trả về một tài liệu văn bản thuần túy (.txt) dưới dạng phản hồi, chúng tôi sử dụng lớp TextSaveOptions và sử dụng text/plain làm loại 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"
    };
}

Chia sẻ URL của Biên tập viên với bạn bè

Chúng tôi nên cung cấp cho người dùng một cách thuận tiện để sao chép URL của người chỉnh sửa và chia sẻ nó với bạn bè. Để thực hiện việc này, hãy thêm một <input> phần tử của loại văn bản trong Index.cshtml.

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

Thêm phần trên <div> phần tử trước <div id="userlist"> thẻ. Chúng tôi đặt giá trị của trường nhập văn bản này thành URL của trình soạn thảo bằng cách sử dụng dòng mã sau. Thêm mã này vào hàm init() trong Index.cshtml.

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

Chúng tôi sẽ thực hiện những thay đổi nhỏ đối với CSS để đảm bảo rằng trường nhập văn bản được hiển thị chính xác. Đặt vị trí trên cùng của firepad và danh sách người dùng thành 100px và thêm lề trái vào trường nhập văn bản.

#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;
}

Chạy dự án, bạn sẽ thấy trường văn bản cho phép bạn sao chép URL của trình chỉnh sửa. Chia sẻ nó với bạn bè của bạn và chỉnh sửa tài liệu cùng lúc với họ.

Mã nguồn hoàn chỉnh của dự án có sẵn trên GitHub.

Xem thêm