Nel primo post del blog, abbiamo creato un’app Web simile a Google Documenti che presenta le seguenti funzionalità:

  • Rich Text Editing (modifica carattere del testo, dimensione, colore, stile (grassetto, corsivo), allineamento ecc.).
  • Modifica collaborativa in tempo reale dello stesso documento. Più utenti possono accedere al documento contemporaneamente e modificarlo.
  • Carica il contenuto di un documento Word esistente in un editor.

In questo post del blog, estenderemo la nostra applicazione web per includere le seguenti funzionalità:

  • Scarica il contenuto dell’editor come documento MS Word, PDF, TXT o HTML.
  • Condividi l’URL con gli amici in modo che possano modificare il documento contemporaneamente.

Il prodotto finale avrà il seguente aspetto:

Google Docs come l'interfaccia dell'app

Scarica il contenuto dell’editor come documento di Microsoft Word

Innanzitutto, aggiungiamo un <input> elemento di tipo invia al nostro modulo per mostrare il pulsante “Scarica documento” sul front-end. Usiamo l’attributo asp-page-handler per specificare il gestore del pulsante. Il nostro elemento del modulo ora appare come segue:

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

Potresti aver notato che abbiamo aggiunto un altro <input> elemento di tipo nascosto. Questo elemento è associato alla proprietà DocumentContent in Index.cshtml.cs. Utilizzeremo questa proprietà per memorizzare il contenuto dell’editor come stringa HTML.

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

Firepad fornisce un altro evento sincronizzato per l’ascolto. Viene attivato quando il nostro client locale modifica il documento e quando tali modifiche sono state scritte correttamente su Firebase. Alleghiamo un callback a questo tipo di evento per impostare il valore della proprietà DocumentContent su firepad.getHtml(). Aggiungi il codice seguente nella funzione init() in 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();
    }
});

Ora implementiamo la funzionalità del gestore OnPostDownloadDocument(). Usiamo la libreria GroupDocs.Editor per salvare i contenuti dell’editor come documento Microsoft Word, che sono archiviati nella proprietà DocumentContent. Il gestore restituisce il documento di Word come risposta all’utente.

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

La variabile UploadedDocumentPath è definita come una stringa volatile per mantenere il valore del percorso del documento caricato tra le sessioni.

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

Si prega di controllare gli articoli Salva documento e Crea documento modificabile da file o markup per saperne di più sulle classi GroupDocs.Editor.

Eseguire il progetto e testare il seguente caso d’uso:

  1. Carica il contenuto di un documento Word esistente in un editor facendo clic sul pulsante Carica documento.
  2. Apporta le modifiche desiderate al contenuto.
  3. Fare clic sul pulsante Scarica documento per scaricare il contenuto aggiornato come documento Word.

Scarica il contenuto dell’editor come documento PDF

È necessario apportare alcune modifiche al gestore OnPostDownloadDocument() per restituire il documento PDF come risposta. Usiamo PdfSaveOptions invece di WordProcessingSaveOptions e utilizziamo application/pdf come tipo 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"
    };
}

Scarica il contenuto dell’editor come documento di testo normale

Per restituire un documento di testo normale (.txt) come risposta, utilizziamo la classe TextSaveOptions e utilizziamo text/plain come tipo 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"
    };
}

Condividi l’URL di un editor con gli amici

Dovremmo fornire agli utenti un modo conveniente per copiare l’URL di un editor e condividerlo con gli amici. Per fare ciò, aggiungi un <input> elemento di tipo testo in Index.cshtml.

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

Aggiungi quanto sopra <div> elemento prima di <div id="userlist"> tag. Impostiamo il valore di questo campo di input di testo sull’URL di un editor utilizzando la seguente riga di codice. Aggiungi questo codice nella funzione init() in Index.cshtml.

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

Apporteremo piccole modifiche al nostro CSS per garantire che il campo di immissione del testo venga visualizzato correttamente. Imposta la posizione superiore di firepad e userlist su 100px e aggiungi un margine sinistro al campo di immissione del testo.

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

Esegui il progetto, dovresti vedere un campo di testo che ti consente di copiare l’URL dell’editor. Condividilo con i tuoi amici e modifica il documento contemporaneamente a loro.

Il codice sorgente completo del progetto è disponibile su GitHub.

Guarda anche