在 第一篇博文 中,我们创建了一个类似 Google Docs 的网络应用程序,它具有以下功能:
- 富文本编辑(更改文本字体、大小、颜色、样式(粗体、斜体)、对齐方式等)。
- 同一文档的实时协作编辑。多个用户可以同时访问文档并对其进行修改。
- 将现有 Word 文档的内容上传到编辑器中。
在这篇博文中,我们将扩展我们的 Web 应用程序以包含以下功能:
- 将编辑器的内容下载为 MS Word、PDF、TXT 或 HTML 文档。
- 与朋友共享 URL,以便他们可以同时编辑文档。
最终产品如下所示:
- 将编辑器的内容下载为
- 与朋友分享编辑器的 URL
将编辑器的内容下载为 Microsoft Word 文档
首先,我们添加一个<input>
类型的元素提交到我们的表单以在前端显示“下载文档”按钮。我们使用 asp-page-handler 属性来指定按钮的处理程序。我们的表单元素现在如下所示:
<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>
您可能已经注意到我们添加了另一个<input>
隐藏类型的元素。此元素绑定到 Index.cshtml.cs 中的 DocumentContent 属性。我们将使用此属性将编辑器的内容存储为 HTML 字符串。
[BindProperty]
public string DocumentContent { get; set; }
Firepad 提供了另一个同步监听的事件。当我们的本地客户端编辑文档并且这些编辑已成功写入 Firebase 时,它会被触发。我们将回调附加到此事件类型,以便将 DocumentContent 属性的值设置为 firepad.getHtml()。请在 Index.cshtml 的 init() 函数中添加以下代码。
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();
}
});
现在我们实现 OnPostDownloadDocument() 处理程序的功能。我们使用 GroupDocs.Editor 库将编辑器的内容保存为 Microsoft Word 文档,存储在 DocumentContent 属性中。处理程序返回 Word 文档作为对用户的响应。
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)
};
}
UploadedDocumentPath 变量被定义为一个可变字符串,以保持会话之间上传文档路径的值。
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();
}
请查看 保存文档 和 从文件或标记创建可编辑文档 文章以了解有关 GroupDocs.Editor 类的更多信息。
运行项目并测试以下用例:
- 通过单击“上传文档”按钮将现有 Word 文档的内容上传到编辑器中。
- 对内容进行所需的更改。
- 单击“下载文档”按钮以将更新的内容下载为 Word 文档。
将编辑器的内容下载为 PDF 文档
我们需要在 OnPostDownloadDocument() 处理程序中进行一些修改以返回 PDF 文档作为响应。我们使用 PdfSaveOptions 而不是 WordProcessingSaveOptions 并使用 application/pdf 作为 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"
};
}
将编辑器的内容下载为纯文本文档
为了返回纯文本文档 (.txt) 作为响应,我们使用 TextSaveOptions 类并使用 text/plain 作为 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"
};
}
与朋友分享编辑器的 URL
我们应该为用户提供一种方便的方式来复制编辑器的 URL 并与朋友分享。为此,请添加一个<input>
Index.cshtml 中文本类型的元素。
<div>
<strong>
<label for="shareURL">Edit with Friends: </label>
</strong>
<input type="text" name="shareURL" id="shareURL" size="50">
</div>
添加上面的<div>
之前的元素`标签。我们使用以下代码行将此文本输入字段的值设置为编辑器的 URL。将此代码添加到 Index.cshtml 的 init() 函数中。
document.getElementById("shareURL").value = window.location.origin + window.location.pathname + window.location.hash;
我们将对 CSS 进行微小的更改,以确保正确显示文本输入字段。将 firepad 和 userlist 的顶部位置设置为 100px,并为文本输入字段添加左边距。
#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;
}
运行项目,您应该会看到一个文本字段,可以让您复制编辑器的 URL。与您的朋友分享并与他们同时编辑文档。
该项目的完整源代码可在 GitHub 上获得。