Unable to view document in word editor properly

Thanks a lot @atir.tahir,

This is just a Trial license and it will get expires in this month, and we also have a demo with a client coming Friday in that demo the client needs to see the functionality of Groupdocs Editor (Word/Excel/PPT). it will be a great help for us if we could get the solution before coming Friday as we are planning to upgrade the license to the latest version based on the Demo.

@Niteen_Jadhav

We’ll try to share a sample application with you.

@Niteen_Jadhav

We have prepared a sample for you. Please take a look here at GitHub.

Hello @atir.tahir,

Thank you for your prompt response, but the project you have shared is developed in .net 6 and we have .net 4.7 in our development environment and hence we are unable to run and test the application.

and also,

  1. It seems like the team who developed the application (thanks for the team to develop this very quickly) used textarea for the editor.

  2. The team used “tinymce” in the project. (can we develop editor without using tinymce)?

  3. The jQuery structure looks very different in the current project.

Viewer Example with version 20.8:

$('#element').viewer({
    applicationPath: '@Model.Server.HostAddress',
    defaultDocument: '@Model.Annotation.GetDefaultDocument()',
    preloadPageCount: @Model.Annotation.GetPreloadPageCount(),
    pageSelector: @Model.Common.pageSelector.ToString().ToLowerInvariant(),
    download: @Model.Common.download.ToString().ToLowerInvariant(),
    upload: @Model.Common.upload.ToString().ToLowerInvariant(),
    print: @Model.Common.print.ToString().ToLowerInvariant(),
    browse: @Model.Common.browse.ToString().ToLowerInvariant(),
    rewrite: @Model.Common.rewrite.ToString().ToLowerInvariant(),
    enableRightClick: @Model.Common.enableRightClick.ToString().ToLowerInvariant(),
});

it will be helpful for us if you provide the sample project using the above details.

@Niteen_Jadhav

Thank you for your feedback on the application.

The GroupDocs.Editor for .NET is a UI-agnostic API, which means we had the flexibility to choose the UI framework and editor we wanted to use for the application.

While we used TinyMCE in this particular implementation, the API itself does not require the use of any specific front-end WYSIWYG HTML editor. Developers have the freedom to integrate the API with the editor of their choice, be it TinyMCE, CKEditor, or any other suitable option.

Regarding the jQuery structure used in the application, we have provided a dedicated wiki page that demonstrates how the GroupDocs.Editor RESTful API for .NET can be accessed using jQuery. This example code is intended to help you understand how the API can be integrated with the front-end, and you are free to adapt it to your own requirements and preferred coding styles.

Thank you @atir.tahir, what can we do with the dot net version?

@Niteen_Jadhav

That is why we prepared this Wiki for you so that you can develop the application from scratch in any .NET framework.

Hello,

Thanks a lot for your prompt response. I have created a project using the example provided by you.

I am facing few errors in this project and I’ll need your help to fix these issues.

I am getting the below error while calling "createNew" Api in my "GroupDocsController" controller

An error has occurred.
An error occurred when trying to create a controller of type ‘GroupDocsController’. Make sure that the controller has a parameterless public constructor.
System.InvalidOperationException
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()

An error has occurred.
Type ‘GroupDocs_Editor.Controllers.GroupDocsController’ does not have a default constructor
System.ArgumentException
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

I am sharing the sample project created by me.

and it’ll be a great help if you add the code to view word/excel/ppt document in the editor in my current solution.

Update: please find the link for the same → GroupDocs Editor.zip - Google Drive

@Niteen_Jadhav

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): EDITORNET-2822

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@Niteen_Jadhav

We updated existing GitHub sample project. This application uses official supported .NET 4.6.2 framework, see more.

Moreover, this MVC application is similar to the Viewer sample, as you asked.

Again the front end is developed in Angular and not in jQuery

@Niteen_Jadhav

Please note that all free support tickets/issues are assisted on first come first served basis. At the moment we have these demo projects (and the documentation) that we already shared with you. Let us further explain how API could be utilized in the UI application.

Take a look at this documentation article - get html markup in different forms.

public IActionResult Index()
{
    License lic = new License();
    lic.SetLicense(@"license file path");
    string inputFilePath = @"D:\\document.pdf"; //path to some document
    Editor editor = new Editor(inputFilePath);

    PdfEditOptions editOptions = new PdfEditOptions();

    EditableDocument readyToEdit = editor.Edit(editOptions);
    string htmlContent = readyToEdit.GetContent();

    ViewBag.HtmlContent = htmlContent;

    TempData["InputFilePath"] = inputFilePath;

    return View();
}

Below is the basic code for the View:

<script src="https://cdn.ckeditor.com/4.16.2/standard/ckeditor.js"></script>

@using (Html.BeginForm("SaveEditedDocument", "Home", FormMethod.Post))
{
    <textarea name="editor1" id="editor1">
        @Html.Raw(ViewBag.HtmlContent)
        </textarea>
    <script>
        CKEDITOR.replace('editor1');
    </script>
    <input type="submit" value="Save Changes" />
    @Html.Hidden("inputFilePath", TempData["InputFilePath"].ToString())
}

And following code to save the updated (content updated using CKEDITOR) document:

public ActionResult SaveEditedDocument(string editor1, string inputFilePath)
{
    string editedHtmlContent = editor1;

    // Create an EditableDocument from the edited HTML content
    EditableDocument afterEdit = EditableDocument.FromMarkup($"<body>{editedHtmlContent}</body>", null);

    // Define the output file path and save options
    string outputFilePath = @"D:\\output.pdf";
    PdfSaveOptions saveOptions = new PdfSaveOptions();

    // Use the input file path to create a new Editor instance and save the document
    using (Editor editor = new Editor(inputFilePath))
    {
        editor.Save(afterEdit, outputFilePath, saveOptions);
    }

    return RedirectToAction("Index");
}

Edit and save options could be changed as per the source file/format (e.g. PdfEditOptions, WordProcessingEditOptions, PdfSaveOptions or WordProcessingSaveOptions).

We procedded with TinyMCE, but we have few questions,

  1. Do we need to buy TinyMCE separately.

  2. There is a issue while we save the file.

  3. When Will We get the project in asp.net mvc and jQuery Combined.

ad59c511-a785-477a-83ae-a9b9759b32af…docx (8.3 KB)

Above file for your reference.
Code below.

<div>
    <textarea id="documentContent">@Html.Raw(Model.HtmlContent)</textarea>
    <button id="btnSave" class="btn btn-primary">Save</button>
</div>

<script>
    tinymce.init({
        selector: '#documentContent',
        height: 500,
        plugins: 'advlist autolink lists link image charmap print preview hr anchor pagebreak',
        toolbar_mode: 'floating',
        toolbar: 'undo redo | formatselect | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
        content_style: `@Html.Raw(Model.CssContent)`
    });
    $('#btnSave').click(function () {
        let SaveDetails = {
            FileId: $('#FileId').val(),
            GUID: $('#FileServerId').val(),
            EditorData: $('#documentContent').html(),
        }
        ajaxCallFunction("POST", "/api/Document/Document/SaveWordFile", JSON.stringify(SaveDetails), function (response) {

        });
    });
</script>

API →

[HttpPost]
[Route("api/GroupDocsApi/SaveWordFile")]
public SPResponse SaveWordFile(DocPro.DMS.BusinessEntities.Request.GroupDocs.GetDocumentInfoRequest request)
{
    SPResponse sp = new SPResponse() { ReturnStatus = "-1" };
    string editedHtmlContent = request.EditorData;
    string inputFilePath = Path.Combine(request.StoragePath, request.GUID);
    string guid = Guid.NewGuid().ToString();
    string extension = Path.GetExtension(request.GUID);
    string outputFilePath = Path.Combine(request.StoragePath, guid + "." + extension);


    // Create an EditableDocument from the edited HTML content
    EditableDocument afterEdit = EditableDocument.FromMarkup($"<body>{editedHtmlContent}</body>", null);

    WordProcessingSaveOptions saveOptions = new WordProcessingSaveOptions();

    // Use the input file path to create a new Editor instance and save the document
    using (Editor editor = new Editor(inputFilePath))
    {
        editor.Save(afterEdit, outputFilePath, saveOptions);
    }
    sp = new SPResponse() { ReturnStatus = "0", Ref1 = guid };
    return sp;
}

@Niteen_Jadhav

We’ll let you know once the demo is available.

Please share this specific source file.

Original File
GroupdocsEditor.docx (471.2 KB)

After saving from editor
GroupdocsEditor (1).docx (7.8 KB)

It’ll be better if you can come up with a solution on this.

@Niteen_Jadhav

We already explained that GroupDocs.Editor for .NET is a UI-Agnostic API, you can use any WYSIWYG HTML editor at front end (paid or free).

We already shared file saving code with you that works perfectly fine.

We have plans to develop more demo projects but we do not have any ETA at the moment.

Please take a look at the output.zip (435.7 KB) we are getting using the same code. A new text line is also added at the bottom of the file through the editor “multiple images ahead”. Please reevaluate the save method we shared earlier with you.

Can you please suggest us a good WYSIWYG HTML editor for office docs which are not paid and will work with Groupdocs Editor

We used the same code but we are facing the issue, code and doc file already shared.
We are not using post method instead we are using ajax call.

Ok, Thanks a lot

I think is it because of the way I am passing the request to the api →

let SaveDetails = {
    FileId: $('#FileId').val(),
    GUID: $('#FileServerId').val(),
    EditorData: $('#documentContent').html(),
}

and I want to add one more thing when I open the document in Editor and the document contains a header the alignment of the document gets affected, sharing the file and screenshot for your reference.

Document Editor issue with header.png (291.9 KB)

GroupdocsEditor.docx (2.3 MB)

@Niteen_Jadhav

All WYSIWYG HTML editors are supported. We are using CKEditor.

This is a front end level issue, please debug/troubleshoot it to find the reason.

Take a look at this image.png (34.2 KB), it is way better than the screenshot you shared. We updated code as per the following documentation articles:

Below is the updated code:

public IActionResult Index()
{
    // Set the license for the Conholdate.Total.Product.Family library
    License lic = new License();
    lic.SetLicense(@"D:\\GD Licenses\\Conholdate.Total.Product.Family.lic");
     
    // Specify the input file path for the Word document
    string inputFilePath = @"D:\\GroupdocsEditor.docx";

    // Define the resource directory where the extracted resources will be saved
    string resourceDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images");

    // Ensure the resource directory exists
    Directory.CreateDirectory(resourceDirectory);

    // Initialize the editor with the input file path
    Editor editor = new Editor(inputFilePath);

    // Set the Word processing edit options
    WordProcessingEditOptions editOptions = new WordProcessingEditOptions();
    editOptions.UseInlineStyles = true;

    // Edit the document and get the editable document instance
    EditableDocument beforeEdit = editor.Edit(editOptions);

    // Extract various resources from the editable document
    List<IImageResource> images = beforeEdit.Images;
    List<FontResourceBase> fonts = beforeEdit.Fonts;
    List<CssText> stylesheets = beforeEdit.Css;
    List<Mp3Audio> audiofiles = beforeEdit.Audio;

    // Get the HTML content of the editable document
    string htmlContent = beforeEdit.GetContent();

    // Save the extracted fonts, stylesheets, and audio files to the resource directory
    foreach (FontResourceBase oneFont in fonts)
    {
        oneFont.Save(Path.Combine(resourceDirectory, oneFont.FilenameWithExtension));
    }
    foreach (CssText oneStylesheet in stylesheets)
    {
        oneStylesheet.Save(Path.Combine(resourceDirectory, oneStylesheet.FilenameWithExtension));
    }
    foreach (Mp3Audio oneMp3 in audiofiles)
    {
        oneMp3.Save(Path.Combine(resourceDirectory, oneMp3.FilenameWithExtension));
    }

    // Update the HTML content to reference the saved images
    htmlContent = beforeEdit.GetContent();
    foreach (var image in images)
    {
        string imageFileName = Path.GetFileName(image.FilenameWithExtension);
        string imageFilePath = Path.Combine(resourceDirectory, imageFileName);

        // Save the image to the resource directory
        using (var fileStream = new FileStream(imageFilePath, FileMode.Create))
        {
            using (var imageStream = image.ByteContent)
            {
                imageStream.CopyTo(fileStream);
            }
        }

        // Update the HTML content to reference the correct image path
        htmlContent = htmlContent.Replace(image.FilenameWithExtension, $"/images/{imageFileName}");
    }

    // Optionally, save the updated HTML content to a "debug.html" file for debugging purposes
    System.IO.File.WriteAllText(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "debug.html"), htmlContent);

    // Pass the updated HTML content to the view using ViewBag
    ViewBag.HtmlContent = htmlContent;

    // Pass the input file path to the view using TempData
    TempData["InputFilePath"] = inputFilePath;

    return View();
}

We’d again recommend you to please go through the documentation and existing UI applications.

Yes the image shared by you is much better than what we are achieving but still not looking like the original file.

NOTE: We had fixed the saving issue by changing from $(‘#documentContent’).html() to $(‘#documentContent’).text() before doing the api call, but I want to know one more thing

Below is the code to load the word file →

SPResponse sp = new SPResponse() { ReturnStatus = "-1" };
Editor editor = new Editor(request.FileUploadPath);
WordProcessingEditOptions editOptions = new WordProcessingEditOptions();
editOptions.UseInlineStyles = true;
EditableDocument readyToEdit = editor.Edit(editOptions);
List<IImageResource> images = readyToEdit.Images;

// Save extracted images and update HTML content
string htmlContent = readyToEdit.GetContent();
foreach (var image in images)
{
    string imageFileName = Path.GetFileName(image.FilenameWithExtension);
    string imageFilePath = Path.Combine(request.ResourceDirectory, imageFileName);

    // Save image to the resource directory
    using (var fileStream = new FileStream(imageFilePath, FileMode.Create))
    {
        using (var imageStream = image.ByteContent)
        {
            await imageStream.CopyToAsync(fileStream);
        }
    }
    htmlContent = htmlContent.Replace(image.FilenameWithExtension, request.AppDirectory + "\\" + imageFileName);
}
string cssContent = string.Join("\n", readyToEdit.GetCssContent());
sp.Ref1 = htmlContent;
sp.Ref2 = cssContent;
return sp;

and my saveFile Code

SPResponse sp = new SPResponse() { ReturnStatus = "-1" };
string editedHtmlContent = request.EditorData;
string inputFilePath = Path.Combine(request.StoragePath, request.GUID);
string guid = Guid.NewGuid().ToString();
string extension = Path.GetExtension(request.GUID);
string outputFilePath = Path.Combine(request.StoragePath, guid + "." + extension);


// Create an EditableDocument from the edited HTML content

EditableDocument afterEdit = EditableDocument.FromMarkup($"<body>{editedHtmlContent}</body>", null);

WordProcessingSaveOptions saveOptions = new WordProcessingSaveOptions();

// Use the input file path to create a new Editor instance and save the document
using (Editor editor = new Editor(inputFilePath))
{
    editor.Save(afterEdit, outputFilePath, saveOptions);
}
sp = new SPResponse() { ReturnStatus = "0", Ref1 = guid };
return sp;

can you please help me with how to also save images with the document as the images are not getting save while saving the document.

@Niteen_Jadhav

We already explained how to load and save document containing images in this thread GroupDocs Editor: Images are not loading