Birkaç müşteri bize ulaştı ve API’lerimizi kullanarak Google Dokümanlar benzeri bir web uygulamasını nasıl oluşturabileceklerini sordu. Google Dokümanlar, kullanıcıların diğer kullanıcılarla gerçek zamanlı olarak işbirliği yaparken çevrimiçi olarak dosya oluşturmasına ve düzenlemesine olanak tanıyan bir kelime işlemcidir.

Bu blog gönderisinde, Google Dokümanlar’ın aşağıdaki özelliklere sahip basit bir sürümünü oluşturmanın ne kadar kolay olduğu açıklanmaktadır:

  • Zengin Metin Düzenleme (metnin yazı tipini, boyutunu, rengini, stilini (kalın, italik), hizalamasını vb. değiştirin).
  • Aynı belgenin gerçek zamanlı ortak düzenlemesi. Birden fazla kullanıcı aynı anda belgeye erişebilir ve üzerinde değişiklik yapabilir.
  • Mevcut bir Word Belgesinin içeriğini bir düzenleyiciye yükleyin.
  • Düzenleyicideki metni MS Word, PDF, TXT veya HTML belgesi olarak kaydedin.

Son ürünümüz aşağıdaki gibi görünecek:

Google Dokümanlar Uygulama Arayüzü gibi

Araçlar ve Teknolojiler – Uygulamaya benzer Google Dokümanları oluşturun

ASP.NET Core’da Google Dokümanlar benzeri web uygulamasını geliştireceğiz ve aşağıdaki iki kütüphaneyi kullanacağız:

  • Şömine pedi 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 için 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.

IDE olarak Visual Studio for Mac‘i kullandım. Ancak platformunuza bağlı olarak Visual Studio’nun ücretsiz topluluk sürümünü [buradan]13 adresinden indirebilirsiniz. Hadi başlayalım.

Yeni bir ASP.NET Core Web Uygulaması projesi oluşturun ve projeye “GoogleDocsLite" adını verin.

Yeni bir ASP.NET Core Web Uygulaması oluşturun

Her şeyin doğru şekilde ayarlandığından emin olmak için uygulamayı çalıştırın.

Firepad’i entegre edin

Aşağıdaki JavaScript dosyalarını web uygulamamıza ekleyerek Firepad’i ekleyebiliriz. Layout.cshtml’nin bölümü.

<!-- 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 oluşturmak için Firebase, CodeMirror ve ardından Firepad’i başlatacağız. Aşağıdaki betiği ve HTML kodunu Index.cshtml’ye ekleyin.

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

Lütfen config içeriğini kendi Firebase projenizin config’iyle değiştirin.

Yukarıdaki betiğin, bir web sayfası tüm içeriği (komut dosyaları, CSS dosyaları vb.) tamamen yükledikten sonra çalıştırılmasını istiyoruz. Bu nedenle, onLoad olay özelliğinden init() işlevini çağırın. Layout.cshtml’deki öğe.

<body onload="init()">

Senin <body> elemanı aşağıdaki gibi görünmelidir. ’ gibi gereksiz etiketler içeriyorsa , `, lütfen bunları kaldırın.

Gövde Elemanı

Projeyi çalıştırırsanız firepad ve kullanıcı listesinin düzgün şekilde hizalanmadığını fark edeceksiniz. Firepad’in ve kullanıcı listesinin boyutunu/konumunu ayarlamak için lütfen aşağıdaki CSS kodunu kullanın. İçine aşağıdaki kodu ekleyebilirsiniz Layout.cshtml’nin öğesi.

<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 başarıyla kuruldu.

Mevcut Bir Word Belgesinin İçeriğini Düzenleyiciye Yükleme

Artık kullanıcılarımıza mevcut bir Word Belgesinin içeriğini metin düzenleyiciye yüklemeleri için bir yol sunmak istiyoruz. Ön uçta bir ekliyoruz Kullanıcının yerel makinesinden bir Word Belgesi seçmesine olanak tanıyan dosya türü öğesi. Arka uçta, bir Word Belgesinin içeriğini HTML dizesi olarak almak için GroupDocs.Editor kitaplığını kullanırız. Son olarak metin düzenleyicide içeriği göstermek için Firepad’in setHtml() yöntemini kullanıyoruz.

Aşağıdakileri ekleyin daha önce Index.cshtml dosyasındaki öğe etiket.

<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 dosyasında karşılık gelen bir özelliği tanımlayın.

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

Projeyi çalıştırın ve Dosya seç butonuna tıklayın. Yüklemek istediğiniz Word Belgesini seçin ve Belge Yükle butonuna tıklayın. İşleyiciyi henüz Index.cshtml.cs’de tanımlamadığımız için hiçbir şey olmayacak. Bunu yapmadan önce ilk olarak projemize GroupDocs.Editor kütüphanesini ekleyelim.

GroupDocs.Editor’ı entegre edin

GroupDocs.Editor NuGet paketi olarak mevcut olduğundan projemize kolaylıkla ekleyebiliriz. Projeye sağ tıklayın ve NuGet Paketlerini Yönet seçeneğini seçin. NuGet Paketlerini Yönet penceresi açılacaktır, Gözat sekmesini seçin ve arama alanına GroupDocs.Editor yazın. GroupDocs.Editor ilk sonuç olarak görünmelidir, onu seçin ve ardından Paket Ekle düğmesine tıklayın.

NuGet Paket Yöneticisi aracılığıyla GroupDocs.Editor'ı ekleyin

Paket başarıyla eklendiğinde Bağımlılıklar klasöründeki NuGet alt klasörü altında görünecektir.

Form Verilerinin Kullanımı

Şimdi kullanıcı Belge Yükle butonuna tıkladığında çağrılacak bir işleyici (OnPostUploadDocument() yöntemi) yazıyoruz. UploadedDocument nesnesi (IFormFile türünde) yüklenen belgenin içeriğini içerir. Öncelikle belgeyi sunucuya kaydediyoruz, ardından içeriğini HTML dizisi olarak almak için GroupDocs.Editor kütüphanesini kullanıyoruz. Lütfen aşağıdaki kodu Index.cshtml.cs dosyasına ekleyin.

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 dinleme için iki etkinlik sağlar. Bunlardan biri ‘hazırdır’ ve Firepad ilk düzenleyici içeriğini aldığında tetiklenir. Bu olay türüne bir geri çağrı ekliyoruz ve geri aramada, Firepad nesnesinin setHtml() yöntemine argüman olarak DocumentContent dizesini iletiyoruz. Lütfen aşağıdaki kodu Index.cshtml’deki init() işlevine ekleyin.

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() yöntemine geçmeden önce, documentContent dizesini ilk olarak htmlDecode() yöntemine aktardığımızı fark etmişsinizdir. <, > gibi karakter varlıklarını işaretlerle (< ve >) değiştirmektir. htmlDecode() yöntemi aşağıdaki gibi görünür.

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

Projeyi çalıştırın, artık bir Word Belgesinin içeriğini bir düzenleyiciye yükleyebilmelisiniz.

Bu yazının Bölüm II bölümünde, uygulamamızı aşağıdaki özellikleri içerecek şekilde nasıl genişletebileceğimizi açıkladım:

  • Düzenleyicinin içeriğini MS Word, PDF, TXT veya HTML belgesi olarak indirin.
  • Belgeyi aynı anda düzenleyebilmeleri için URL’yi arkadaşlarınızla paylaşın.

Lütfen kontrol edin.

Projenin kaynak kodunun tamamı GitHub adresinde mevcuttur.

Ayrıca bakınız