How to download an edited word document using .NET web API and Angular

1k Views Asked by At

What I'm Trying To Do

I inherited an angular project and am new to the framework. I am trying to open a macro enabled word document using Spire.Doc (free version) and edit the file, then send the edited file to the client. I am calling a. Net Core 3 Web API from an angular component through a report service. I need to send an ID to the API, open and edit the word file, then send it back to the client.

What I'm Getting

I have had various results from all of the changes I have tried. With the code below, I am able to download a word document, but the one page file is now 54 pages of random characters (wrong encoding?).

My Code

client.component.ts

public createForm() {
this.reportService.GetForm(this.clientId);
}

reports.service.ts

GetForm(clientId: string) {
    let params = new HttpParams()
        .set('clientId', clientId);
    this.http.get(environment.apiUrl + '/Reports/GenerateForm', { params: params, responseType: 'blob' })
        .subscribe(response => {
            let blob = new Blob([response], { type: 'application/msword' });
            const fileName = "Test Word Document.doc";
            saveAs(blob, fileName);
        });
}

ReportsController.cs

[HttpGet("GenerateReimbursementForm")]
public async Task<ActionResult<HttpResponseMessage>> GenerateForm(int clientId)
{
    var loggedInUser = this.GetLoggedInUser(this._context);
    if (!loggedInUser.HasSystemAccess)
        return Forbid();

    // get document
    string filename = "Test Word Document.doc";
    string path = Path.Combine(
        Directory.GetCurrentDirectory(), 
        "documents", 
        filename);

    Spire.Doc.Document doc = new Spire.Doc.Document(path);

    // do stuff to document
    Spire.Doc.Documents.Paragraph p = doc.CreateParagraph();
    p.Text = "testing...";

    //get stream from document in memory
    MemoryStream ms = new MemoryStream();
    doc.SaveToFile(ms, Spire.Doc.FileFormat.Doc);
    ms.Position = 0;

    // send to browser in http response message
    var result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new StreamContent(ms);
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    result.Content.Headers.ContentDisposition.FileName = filename;
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentLength = ms.Length;

    return result;
}

Things I've Tried

  • Different word document - same result
  • Different word types (docx, docm) - word says it is a corrupted file
  • Using different type values (all with the same result):
    • blob
    • application/vnd.openxmlformats-officedocument.wordprocessingml.document
    • arraybuffer
  • Adding charset:utf-8; to type string
  • Removing the Spire.Doc code - same result
  • Return a byte[] from controller instead of HttpResponseMessage using memoryStream.ToArray() - same result
  • Create and save the blob in the component code rather than the service - same result
  • make the link button redirect to the controller path and skip the .ts files - unable to get this method to work due to path issues

Any help is appreciated!

Edit

When making a GET request through Postman I receive the following:

{"version":{"major":"1","minor":"1","build":"-1","revision":"-1","majorRevision":-1,"minorRevision":-1},"content":{"headers":[{"Key":"Content-Disposition","Value":["attachment; filename=\"Test Word Document.doc\""]},{"Key":"Content-Type","Value":["application/octet-stream"]},{"Key":"Content-Length","Value":["16384"]}]},"statusCode":200,"reasonPhrase":"OK","headers":[],"trailingHeaders":[],"requestMessage":null,"isSuccessStatusCode":true}
0

There are 0 best solutions below