Im ersten Blogpost haben wir eine Google Docs-ähnliche Web-App mit den folgenden Funktionen erstellt:

  • Rich-Text-Bearbeitung (Ändern von Schriftart, -größe, -farbe, -stil (fett, kursiv), Ausrichtung usw.).
  • Gemeinsame Bearbeitung desselben Dokuments in Echtzeit. Mehrere Benutzer können gleichzeitig auf das Dokument zugreifen und es ändern.
  • Laden Sie den Inhalt eines bestehenden Word-Dokuments in einen Editor hoch.

In diesem Blogbeitrag erweitern wir unsere Webanwendung um folgende Features:

  • Laden Sie den Inhalt des Editors als MS Word-, PDF-, TXT- oder HTML-Dokument herunter.
  • Teilen Sie die URL mit Freunden, damit diese das Dokument gleichzeitig bearbeiten können.

Das Endprodukt wird wie folgt aussehen:

Google Docs wie App Interface

Laden Sie den Inhalt des Editors als Microsoft Word-Dokument herunter

Zuerst fügen wir ein hinzu<input>-Element vom Typ „Senden“ an unser Formular, um die Schaltfläche „Dokument herunterladen“ im Frontend anzuzeigen. Wir verwenden das asp-page-handler-Attribut, um den Handler der Schaltfläche anzugeben. Unser Formularelement sieht nun wie folgt aus:

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

Sie haben vielleicht bemerkt, dass wir ein weiteres hinzugefügt haben<input> Element vom Typ versteckt. Dieses Element ist an die DocumentContent-Eigenschaft in Index.cshtml.cs gebunden. Wir werden diese Eigenschaft verwenden, um den Inhalt des Editors als HTML-String zu speichern.

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

Firepad bietet ein weiteres zum Abhören synchronisiertes Ereignis. Es wird ausgelöst, wenn unser lokaler Client das Dokument bearbeitet und diese Änderungen erfolgreich in Firebase geschrieben wurden. Wir hängen einen Rückruf an diesen Ereignistyp an, um den Wert der DocumentContent-Eigenschaft auf firepad.getHtml() zu setzen. Bitte fügen Sie den folgenden Code in die init()-Funktion in Index.cshtml ein.

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

Jetzt implementieren wir die Funktionalität des Handlers OnPostDownloadDocument(). Wir verwenden die Bibliothek GroupDocs.Editor, um den Inhalt des Editors als Microsoft Word-Dokument zu speichern, das in der Eigenschaft DocumentContent gespeichert ist. Der Handler gibt das Word-Dokument als Antwort an den Benutzer zurück.

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

Die Variable UploadedDocumentPath ist als flüchtige Zeichenfolge definiert, um den Wert des hochgeladenen Dokumentpfads zwischen Sitzungen beizubehalten.

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

Weitere Informationen zu GroupDocs.Editor-Klassen finden Sie in den Artikeln Dokument speichern und Bearbeitbares Dokument aus Datei oder Markup erstellen.

Führen Sie das Projekt aus und testen Sie den folgenden Anwendungsfall:

  1. Laden Sie den Inhalt eines bestehenden Word-Dokuments in einen Editor hoch, indem Sie auf die Schaltfläche Dokument hochladen klicken.
  2. Nehmen Sie die gewünschten Änderungen am Inhalt vor.
  3. Klicken Sie auf die Schaltfläche Dokument herunterladen, um den aktualisierten Inhalt als Word-Dokument herunterzuladen.

Inhalt des Editors als PDF-Dokument herunterladen

Wir müssen einige Änderungen im Handler OnPostDownloadDocument() vornehmen, um das PDF-Dokument als Antwort zurückzugeben. Wir verwenden PdfSaveOptions anstelle von WordProcessingSaveOptions und verwenden application/pdf als MIME-Typ.

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

Laden Sie den Inhalt des Editors als Nur-Text-Dokument herunter

Um ein reines Textdokument (.txt) als Antwort zurückzugeben, verwenden wir die Klasse TextSaveOptions und verwenden text/plain als MIME-Typ.

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

URL eines Editors mit Freunden teilen

Wir sollten Benutzern eine bequeme Möglichkeit bieten, die URL eines Editors zu kopieren und mit Freunden zu teilen. Fügen Sie dazu ein hinzu<input> Element vom Typ Text in Index.cshtml.

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

Fügen Sie das obige hinzu<div> Element vor <div id="userlist"> -Tag. Wir setzen den Wert dieses Texteingabefelds auf die URL eines Editors, indem wir die folgende Codezeile verwenden. Fügen Sie diesen Code in der init()-Funktion in Index.cshtml hinzu.

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

Wir werden kleinere Änderungen an unserem CSS vornehmen, um sicherzustellen, dass das Texteingabefeld richtig angezeigt wird. Legen Sie die obere Position von Firepad und Benutzerliste auf 100 Pixel fest und fügen Sie dem Texteingabefeld einen linken Rand hinzu.

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

Führen Sie das Projekt aus, Sie sollten ein Textfeld sehen, in das Sie die URL des Editors kopieren können. Teilen Sie es mit Ihren Freunden und bearbeiten Sie das Dokument gleichzeitig mit ihnen.

Der vollständige Quellcode des Projekts ist auf GitHub verfügbar.

Siehe auch