첫 번째 블로그 게시물에서 우리는 다음과 같은 기능을 가진 웹 앱과 같은 Google 문서도구를 만들었습니다.

  • 서식 있는 텍스트 편집(텍스트 글꼴, 크기, 색상, 스타일(굵게, 기울임꼴), 정렬 등 변경).
  • 동일한 문서의 실시간 공동 편집. 여러 사용자가 동시에 문서에 액세스하여 수정할 수 있습니다.
  • 기존 Word 문서의 콘텐츠를 편집기에 업로드합니다.

이 블로그 게시물에서는 다음 기능을 포함하도록 웹 애플리케이션을 확장할 것입니다.

  • 편집기의 내용을 MS Word, PDF, TXT 또는 HTML 문서로 다운로드하십시오.
  • 친구와 URL을 공유하여 동시에 문서를 편집할 수 있습니다.

최종 제품은 다음과 같이 보일 것입니다.

앱 인터페이스와 같은 Google 문서

편집기 콘텐츠를 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 라이브러리를 사용하여 편집기의 내용을 DocumentContent 속성에 저장되는 Microsoft Word 문서로 저장합니다. 핸들러는 사용자에 대한 응답으로 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 클래스에 대한 자세한 내용은 문서 저장파일 또는 마크업에서 EditableDocument 생성 문서를 확인하십시오.

프로젝트를 실행하고 다음 사용 사례를 테스트합니다.

  1. 문서 업로드 버튼을 클릭하여 기존 Word 문서의 내용을 편집기에 업로드합니다.
  2. 내용을 원하는 대로 변경합니다.
  3. 문서 다운로드 버튼을 클릭하여 업데이트된 콘텐츠를 Word 문서로 다운로드합니다.

편집기의 콘텐츠를 PDF 문서로 다운로드

PDF 문서를 응답으로 반환하려면 OnPostDownloadDocument() 처리기를 몇 가지 수정해야 합니다. WordProcessingSaveOptions 대신 PdfSaveOptions을 사용하고 MIME 유형으로 application/pdf를 사용합니다.

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> 앞의 요소 <div id="userlist"> 태그. 다음 코드 줄을 사용하여 이 텍스트 입력 필드의 값을 편집기의 URL로 설정합니다. Index.cshtml의 init() 함수에 이 코드를 추가합니다.

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

텍스트 입력 필드가 제대로 표시되도록 CSS를 약간 변경합니다. 파이어패드 및 사용자 목록의 상단 위치를 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에서 사용할 수 있습니다.

또한보십시오