여러 고객이 우리에게 접근하여 API를 사용하여 웹 앱과 같은 Google 문서도구를 만드는 방법을 문의했습니다. Google 문서도구는 사용자가 실시간으로 다른 사용자와 공동 작업하면서 온라인으로 파일을 만들고 편집할 수 있는 워드 프로세서입니다.

이 블로그 게시물은 다음과 같은 기능이 있는 Google 문서의 라이트 버전을 만드는 것이 얼마나 쉬운지 설명합니다.

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

최종 제품은 다음과 같습니다.

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

도구 및 기술 – 앱과 같은 Google 문서 만들기

ASP.NET Core에서 웹 앱과 같은 Google 문서를 개발하고 다음 두 라이브러리를 사용합니다.

  • 파이어패드 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.
  • .NET용 GroupDocs.Editor 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.

저는 Mac용 Visual StudioIDE로 사용했습니다. 그러나 플랫폼에 따라 여기에서 Visual Studio의 무료 커뮤니티 에디션을 다운로드할 수 있습니다. 시작하자.

새 ASP.NET Core 웹 애플리케이션 프로젝트를 만들고 프로젝트 이름을 “GoogleDocsLite"로 지정합니다.

새 ASP.NET Core 웹앱 만들기

애플리케이션을 실행하여 모든 것이 올바르게 설정되었는지 확인하십시오.

파이어패드 통합

다음 JavaScript 파일을 포함하여 웹 앱에 Firepad를 추가할 수 있습니다. 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" />

Firepad를 생성하기 위해 Firebase, CodeMirror, Firepad를 초기화합니다. Index.cshtml에 다음 스크립트와 HTML 코드를 추가합니다.

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

config의 내용을 자신의 Firebase 프로젝트 구성으로 바꾸세요.

웹 페이지가 모든 콘텐츠(스크립트 파일, CSS 파일 등)를 완전히 로드하면 위의 스크립트가 실행되기를 원합니다. 따라서 onLoad 이벤트 속성에서 init() 함수를 호출하십시오. Layout.cshtml의 요소입니다.

<body onload="init()">

당신의 <body> 요소는 다음과 같아야 합니다. 와 같은 불필요한 태그가 포함된 경우<header> , <footer> , 제거하십시오.

본체 요소

프로젝트를 실행하면 파이어패드와 사용자 목록이 제대로 정렬되지 않은 것을 알 수 있습니다. 다음 CSS 코드를 사용하여 파이어패드 및 사용자 목록의 크기/위치를 조정하십시오. 안에 다음 코드를 추가할 수 있습니다. 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가 성공적으로 설정되었습니다.

기존 Word 문서의 콘텐츠를 편집기에 업로드

이제 우리는 사용자에게 텍스트 편집기에서 기존 Word 문서의 콘텐츠를 업로드할 수 있는 방법을 제공하고자 합니다. 프론트엔드에서 우리는 사용자가 로컬 시스템에서 Word 문서를 선택할 수 있도록 하는 파일 유형 요소입니다. 백엔드에서 GroupDocs.Editor 라이브러리를 사용하여 Word 문서의 내용을 HTML 문자열로 검색합니다. 마지막으로 Firepad의 setHtml() 메서드를 사용하여 텍스트 편집기에 내용을 표시합니다.

다음을 추가하십시오 이전 Index.cshtml 파일의 요소 꼬리표.

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

Index.cshtml.cs 파일에서 해당 속성을 정의합니다.

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

프로젝트를 실행하고 파일 선택 버튼을 클릭합니다. 업로드할 Word 문서를 선택하고 문서 업로드 버튼을 클릭합니다. Index.cshtml.cs에서 처리기를 아직 정의하지 않았기 때문에 아무 일도 일어나지 않습니다. 이 작업을 수행하기 전에 먼저 프로젝트에 GroupDocs.Editor 라이브러리를 추가해 보겠습니다.

GroupDocs.Editor 통합

GroupDocs.Editor는 NuGet 패키지로 제공되므로 프로젝트에 쉽게 추가할 수 있습니다. 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 NuGet 패키지 관리 옵션을 선택합니다. NuGet 패키지 관리 창이 열리고 찾아보기 탭을 선택한 다음 검색 필드에 GroupDocs.Editor를 입력합니다. GroupDocs.Editor가 첫 번째 결과로 나타나야 선택하고 패키지 추가 버튼을 클릭합니다.

NuGet 패키지 관리자를 통해 GroupDocs.Editor 추가

패키지가 성공적으로 추가되면 종속성 폴더의 NuGet 하위 폴더에 나타납니다.

양식 데이터 처리

이제 사용자가 문서 업로드 버튼을 클릭할 때 호출되는 핸들러(OnPostUploadDocument() 메서드)를 작성합니다. UploadedDocument 개체(IFormFile 유형)에는 업로드된 문서의 내용이 포함됩니다. 먼저 서버에 문서를 저장한 다음 GroupDocs.Editor 라이브러리를 사용하여 콘텐츠를 HTML 문자열로 가져옵니다. Index.cshtml.cs 파일에 다음 코드를 추가해주세요.

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는 청취를 위한 두 가지 이벤트를 제공합니다. 그 중 하나는 Firepad가 초기 편집기 내용을 검색하면 실행되는 ‘준비’입니다. 이 이벤트 유형에 콜백을 첨부하고 콜백에서 DocumentContent 문자열을 firepad 객체의 setHtml() 메서드에 대한 인수로 전달합니다. Index.cshtml의 init() 함수에 다음 코드를 추가해주세요.

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

setHtml() 메소드에 전달하기 전에 documentContent 문자열을 htmlDecode() 메소드에 먼저 전달한 것을 눈치채셨을 것입니다. <, >와 같은 문자 엔터티를 기호(<>)로 대체하는 것입니다. htmlDecode() 메서드는 다음과 같습니다.

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

프로젝트를 실행하면 이제 Word 문서의 내용을 편집기에 업로드할 수 있습니다.

이 게시물의 파트 II에서 다음 기능을 포함하도록 애플리케이션을 확장하는 방법을 설명했습니다.

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

확인하십시오.

프로젝트의 전체 소스 코드는 GitHub에서 사용할 수 있습니다.

또한보십시오