Mehrere Kunden sind auf uns zugekommen und haben gefragt, wie sie mit unseren APIs eine Google Docs-ähnliche Webanwendung erstellen können. Google Docs ist ein Textverarbeitungsprogramm, mit dem Benutzer Dateien online erstellen und bearbeiten und gleichzeitig mit anderen Benutzern in Echtzeit zusammenarbeiten können.

In diesem Blogbeitrag wird erläutert, wie einfach es ist, eine Lite-Version von Google Docs mit den folgenden Funktionen zu erstellen:

  • 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.
  • Text im Editor als MS Word-, PDF-, TXT- oder HTML-Dokument speichern.

Unser Endprodukt wird wie folgt aussehen:

Google Docs wie App Interface

Tools und Technologien – Erstellen Sie Google Docs wie eine App

Wir werden die Google Docs-ähnliche Web-App in ASP.NET Core entwickeln und die folgenden zwei Bibliotheken verwenden:

  • Feuerstelle is an open-source, collaborative text editor. It uses the Firebase Realtime Database as a backend so it requires no server-side code and can be added to any web app simply by including the JavaScript files.
  • GroupDocs.Editor für .NET gives us an ability to edit most popular document formats using any WYSIWYG editor without any additional applications. We will load document via GroupDocs.Editor into Firepad, edit document in a way we want and save it back to original document format.

Ich habe Visual Studio für Mac als IDE verwendet. Sie können jedoch die kostenlose Community-Edition von Visual Studio je nach Plattform hier herunterladen. Lasst uns beginnen.

Erstellen Sie ein neues ASP.NET Core-Webanwendungsprojekt und nennen Sie das Projekt „GoogleDocsLite“.

Erstellen Sie eine neue ASP.NET Core-Web-App

Führen Sie die Anwendung aus, um sicherzustellen, dass alles richtig eingerichtet ist.

Firepad integrieren

Wir können Firepad zu unserer Web-App hinzufügen, indem wir die folgenden JavaScript-Dateien in die Abschnitt von 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" />

Um ein Firepad zu erstellen, initialisieren wir Firebase, CodeMirror und dann Firepad. Fügen Sie das folgende Skript und den folgenden HTML-Code in Index.cshtml hinzu.

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

Bitte ersetzen Sie den Inhalt von config durch die Konfiguration Ihres eigenen Firebase-Projekts.

Wir möchten, dass das obige Skript ausgeführt wird, sobald eine Webseite alle Inhalte (Skriptdateien, CSS-Dateien usw.) vollständig geladen hat. Rufen Sie also die Funktion init() aus dem onLoad-Ereignisattribut von auf -Element in Layout.cshtml.

<body onload="init()">

Ihr <body> -Element sollte wie folgt aussehen. Wenn es unnötige Tags wie <header> , <footer> , entfernen Sie sie bitte.

Körperelement

Wenn Sie das Projekt ausführen, werden Sie feststellen, dass Firepad und Benutzerliste nicht richtig ausgerichtet sind. Bitte verwenden Sie den folgenden CSS-Code, um die Größe/Position des Firepads und der Benutzerliste anzupassen. Sie können den folgenden Code darin hinzufügen Element von 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 wurde erfolgreich eingerichtet.

Laden Sie den Inhalt eines vorhandenen Word-Dokuments in einen Editor hoch

Jetzt wollen wir unseren Benutzern eine Möglichkeit geben, Inhalte eines bestehenden Word-Dokuments in den Texteditor hochzuladen. Am Frontend fügen wir eine hinzu Element vom Typ Datei, mit dem ein Benutzer ein Word-Dokument von seinem lokalen Computer auswählen kann. Im Backend verwenden wir die Bibliothek GroupDocs.Editor, um den Inhalt eines Word-Dokuments als HTML-Zeichenfolge abzurufen. Schließlich verwenden wir die setHtml()-Methode von Firepad, um Inhalte im Texteditor anzuzeigen.

Fügen Sie Folgendes hinzu -Element in der Datei Index.cshtml zuvor Schild.

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

Definieren Sie in der Datei Index.cshtml.cs eine entsprechende Eigenschaft.

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

Führen Sie das Projekt aus und klicken Sie auf die Schaltfläche Datei auswählen. Wählen Sie ein Word-Dokument aus, das Sie hochladen möchten, und klicken Sie auf die Schaltfläche Dokument hochladen. Es wird nichts passieren, da wir den Handler noch nicht in Index.cshtml.cs definiert haben. Bevor wir dies tun, fügen wir zunächst die GroupDocs.Editor-Bibliothek in unser Projekt ein.

Integrieren Sie GroupDocs.Editor

GroupDocs.Editor ist als NuGet-Paket verfügbar, sodass wir es einfach zu unserem Projekt hinzufügen können. Klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie die Option NuGet-Pakete verwalten aus. Das Fenster „NuGet-Pakete verwalten“ wird geöffnet, wählen Sie die Registerkarte „Durchsuchen“ und geben Sie „GroupDocs.Editor“ in das Suchfeld ein. GroupDocs.Editor sollte als erstes Ergebnis erscheinen, wählen Sie es aus und klicken Sie dann auf die Schaltfläche Paket hinzufügen.

Fügen Sie GroupDocs.Editor über den NuGet-Paket-Manager hinzu

Wenn das Paket erfolgreich hinzugefügt wurde, wird es im Unterordner „NuGet“ im Ordner „Abhängigkeiten“ angezeigt.

Umgang mit Formulardaten

Jetzt schreiben wir einen Handler (Methode OnPostUploadDocument()), der aufgerufen wird, wenn ein Benutzer auf die Schaltfläche „Dokument hochladen“ klickt. Das UploadedDocument-Objekt (vom Typ IFormFile) enthält den Inhalt des hochgeladenen Dokuments. Zuerst speichern wir das Dokument auf dem Server und verwenden dann die GroupDocs.Editor-Bibliothek, um seinen Inhalt als HTML-Zeichenfolge zu erhalten. Bitte fügen Sie den folgenden Code in die Datei Index.cshtml.cs ein.

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 bietet zwei Ereignisse zum Abhören. Einer von ihnen ist „bereit“, der ausgelöst wird, sobald Firepad den ursprünglichen Inhalt des Editors abgerufen hat. Wir hängen einen Rückruf an diesen Ereignistyp an und übergeben im Rückruf die Zeichenfolge DocumentContent als Argument an die Methode setHtml() des Firepad-Objekts. Bitte fügen Sie den folgenden Code in die init()-Funktion in Index.cshtml ein.

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

Sie haben vielleicht bemerkt, dass wir die Zeichenkette documentContent zuerst an die Methode htmlDecode() übergeben haben, bevor sie an die Methode setHtml() übergeben wurden. Es soll Zeichenentitäten wie <, > durch Zeichen (< und >) ersetzen. Die Methode htmlDecode() sieht wie folgt aus.

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

Führen Sie das Projekt aus, jetzt sollten Sie in der Lage sein, den Inhalt eines Word-Dokuments in einen Editor hochzuladen.

In Teil II dieses Beitrags habe ich erklärt, wie wir unsere Anwendung um die folgenden Funktionen erweitern können:

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

Bitte check it out.

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

Siehe auch