create word document with Open XML
Asked Answered
M

3

15

I am creating a sample handler to generate simple Word document.
This document will contains the text Hello world

This is the code I use (C# .NET 3.5),
I got the Word document created but there is no text in it, the size is 0.
How can I fix it?
(I use CopyStream method because CopyTo is available in .NET 4.0 and above only.)

public class HandlerCreateDocx : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        using (MemoryStream mem = new MemoryStream())
        {
            // Create Document
            using (WordprocessingDocument wordDocument =
                WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
            {
                // Add a main document part. 
                MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();

                // Create the document structure and add some text.
                mainPart.Document = new Document();
                Body body = mainPart.Document.AppendChild(new Body());
                Paragraph para = body.AppendChild(new Paragraph());
                Run run = para.AppendChild(new Run());
                run.AppendChild(new Text("Hello world!"));
                mainPart.Document.Save();
                // Stream it down to the browser
                context.Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx");
                context.Response.ContentType = "application/vnd.ms-word.document";
                CopyStream(mem, context.Response.OutputStream);
                context.Response.End();
            }
        }
    }

    // Only useful before .NET 4
    public void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[16 * 1024]; // Fairly arbitrary size
        int bytesRead;

        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, bytesRead);
        }
    }
}
Mckale answered 24/4, 2013 at 14:27 Comment(1)
I recommend using the Open XML Productivity Tool to debug your document. Also consider creating the document in Word first and then use the tool to give you the code that will create the document.Rarity
M
19

This works for me, by putting the streaming code in the outer USING block.

This causes a call to WordprocessingDocument.Close (via the Dispose method).

public void ProcessRequest(HttpContext context)
{
    using (MemoryStream mem = new MemoryStream())
    {
        // Create Document
        using (WordprocessingDocument wordDocument =
            WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
        {
            // Add a main document part. 
            MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();

            // Create the document structure and add some text.
            mainPart.Document = new Document();
            Body body = mainPart.Document.AppendChild(new Body());
            Paragraph para = body.AppendChild(new Paragraph());
            Run run = para.AppendChild(new Run());
            run.AppendChild(new Text("Hello world!"));
            mainPart.Document.Save();
        }

        context.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        context.Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx");
        mem.Seek(0, SeekOrigin.Begin);
        mem.CopyTo(context.Response.OutputStream);
        context.Response.Flush();
        context.Response.End();
    }
}
Mckale answered 24/4, 2013 at 15:49 Comment(2)
Great. I found the solution similar as you post at here but look like it quite late.Dithyramb
We can consider some of point we missing at here: The wordProcessingDocument need to be closed before send to stream. The stream should be start at beginning. Thanks for your post solution at here.Dithyramb
D
2

I have modifed your code to make it work. I can open it correctly after save download it. Please see my modified below. Hope this help.

using (MemoryStream documentStream = new MemoryStream())
{
    using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentStream, WordprocessingDocumentType.Document, true))
    {
        // Add a new main document part. 
        MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
        //Create Document tree for simple document. 
        mainPart.Document = new Document();
        //Create Body (this element contains
        //other elements that we want to include 
        Body body = new Body();
        //Create paragraph 
        Paragraph paragraph = new Paragraph();
        Run run_paragraph = new Run();
        // we want to put that text into the output document 
        Text text_paragraph = new Text("Hello World!");
        //Append elements appropriately. 
        run_paragraph.Append(text_paragraph);
        paragraph.Append(run_paragraph);
        body.Append(paragraph);
        mainPart.Document.Append(body);

        // Save changes to the main document part. 
        mainPart.Document.Save();
        myDoc.Close();
        context.Response.ClearContent();
        context.Response.ClearHeaders();
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        SetContentType(context.Request, context.Response, "Simple.docx");
        documentStream.Seek(0, SeekOrigin.Begin);
        documentStream.CopyTo(context.Response.OutputStream);
        context.Response.Flush();
        context.Response.End();
    }
}
Dithyramb answered 24/4, 2013 at 15:14 Comment(1)
Your answer is redundant. And you throw many useless lines at us that do not change the behavior. I suggest you remove your answer.Niersteiner
M
2
string Filepath = @"C:\Users\infinity\Desktop\zoyeb.docx";
using (var wordprocessingDocument = WordprocessingDocument.Create(Filepath, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
    MainDocumentPart mainPart = wordprocessingDocument.AddMainDocumentPart();
    mainPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
    Body body = mainPart.Document.AppendChild(new Body());
    DocumentFormat.OpenXml.Wordprocessing.Paragraph para = body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
    DocumentFormat.OpenXml.Wordprocessing.Run run = para.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
    run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("siddiq"));
    wordprocessingDocument.MainDocumentPart.Document.Save();
}

go to nuget package manager and install this first into your project

Install-Package DocumentFormat.OpenXml -Version 2.8.1
Molding answered 2/8, 2018 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.