W pierwszym poście na blogu stworzyliśmy aplikację internetową przypominającą Dokumenty Google, która ma następujące funkcje:

  • Edycja tekstu sformatowanego (zmiana czcionki, rozmiaru, koloru, stylu (pogrubienie, kursywa), wyrównanie itp.).
  • Wspólna edycja tego samego dokumentu w czasie rzeczywistym. Wielu użytkowników może jednocześnie uzyskać dostęp do dokumentu i go modyfikować.
  • Prześlij zawartość istniejącego dokumentu programu Word do edytora.

W tym poście na blogu rozszerzymy naszą aplikację internetową o następujące funkcje:

  • Pobierz zawartość edytora jako dokument MS Word, PDF, TXT lub HTML.
  • Udostępnij adres URL znajomym, aby mogli jednocześnie edytować dokument.

Produkt końcowy będzie wyglądał następująco:

Dokumenty Google, takie jak interfejs aplikacji

Pobierz zawartość edytora jako dokument Microsoft Word

Najpierw dodajemy <input> element typu prześlij do naszego formularza, aby wyświetlić przycisk „Pobierz dokument" na interfejsie. Aby określić procedurę obsługi przycisku, używamy atrybutu asp-page-handler. Nasz element formularza wygląda teraz następująco:

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

Być może zauważyłeś, że dodaliśmy kolejny plik <input> element typu ukryty. Ten element jest powiązany z właściwością DocumentContent w Index.cshtml.cs. Użyjemy tej właściwości do przechowywania zawartości edytora jako ciągu HTML.

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

Firepad udostępnia kolejne wydarzenie synchronizowane do nasłuchiwania. Jest uruchamiany, gdy nasz lokalny klient edytuje dokument i gdy te zmiany zostały pomyślnie zapisane w Firebase. Do tego typu zdarzenia dołączamy wywołanie zwrotne, aby ustawić wartość właściwości DocumentContent na firepad.getHtml(). Dodaj następujący kod w funkcji init() w 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();
    }
});

Teraz implementujemy funkcjonalność procedury obsługi OnPostDownloadDocument(). Do zapisania zawartości edytora w postaci dokumentu Microsoft Word, która przechowywana jest we właściwości DocumentContent, wykorzystujemy bibliotekę GroupDocs.Editor. Procedura obsługi zwraca dokument programu Word jako odpowiedź użytkownikowi.

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

Zmienna UploadedDocumentPath jest zdefiniowana jako zmienny ciąg znaków, który przechowuje wartość ścieżki przesłanego dokumentu pomiędzy sesjami.

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

Zapoznaj się z artykułami Save Document i Create EditableDocument from file or markup, aby dowiedzieć się więcej o klasach GroupDocs.Editor.

Uruchom projekt i przetestuj następujący przypadek użycia:

  1. Prześlij zawartość istniejącego dokumentu programu Word do edytora, klikając przycisk Prześlij dokument.
  2. Wprowadź żądane zmiany w treści.
  3. Kliknij przycisk Pobierz dokument, aby pobrać zaktualizowaną treść jako dokument programu Word.

Pobierz zawartość edytora jako dokument PDF

Musimy dokonać kilku modyfikacji w procedurze obsługi OnPostDownloadDocument(), aby w odpowiedzi zwrócić dokument PDF. Używamy PdfSaveOptions zamiast WordProcessingSaveOptions i używamy application/pdf jako typu 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"
    };
}

Pobierz zawartość edytora w postaci zwykłego dokumentu tekstowego

Aby w odpowiedzi zwrócić dokument tekstowy (.txt), używamy klasy TextSaveOptions, a jako typu MIME używamy tekstu/zwykły.

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

Udostępnij adres URL edytora znajomym

Powinniśmy zapewnić użytkownikom wygodną możliwość skopiowania adresu URL edytora i udostępnienia go znajomym. Aby to zrobić, dodaj <input> element typu tekst w Index.cshtml.

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

Dodaj powyższy <div> element przed <div id="userlist"> znacznik. Wartość tego pola wprowadzania tekstu ustawiamy na adres URL edytora, korzystając z poniższego wiersza kodu. Dodaj ten kod w funkcji init() w Index.cshtml.

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

Wprowadzimy drobne zmiany w naszym CSS, aby zapewnić prawidłowe wyświetlanie pola wprowadzania tekstu. Ustaw górną pozycję Firepada i listy użytkowników na 100px i dodaj lewy margines do pola wprowadzania tekstu.

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

Uruchom projekt, powinieneś zobaczyć pole tekstowe, które pozwala skopiować adres URL edytora. Udostępnij go znajomym i edytuj dokument jednocześnie z nimi.

Pełny kod źródłowy projektu dostępny jest na GitHub.

Zobacz też