简体   繁体   中英

C# Open XML HTML to DOCX Spacing

I've been working on my site, and trying to create an Export to Word. The export works well, converting HTML string to DOCX.

I'm trying to figure out how I can adjust the Line Spacing. By Default Word is adding 8pt Spacing After and setting the Line Spacing to double. I would prefer 0 and Single.

Here is the Function I created to Save a Word Document:

private static void SaveDOCX(string fileName, string BodyText, bool isLandScape, double rMargin, double lMargin, double bMargin, double tMargin)
{
    string htmlSectionID = "Sect1";
    //Creating a word document using the the Open XML SDK 2.0
    WordprocessingDocument document = WordprocessingDocument.Create(fileName, WordprocessingDocumentType.Document);

    //create a paragraph
    MainDocumentPart mainDocumenPart = document.AddMainDocumentPart();
    mainDocumenPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
    Body documentBody = new Body();
    mainDocumenPart.Document.Append(documentBody);


    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body>" + BodyText + "</body></html>"));

    // Create alternative format import part.
    AlternativeFormatImportPart formatImportPart = mainDocumenPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, htmlSectionID);

    //ms.Seek(0, SeekOrigin.Begin);

    // Feed HTML data into format import part (chunk).
    formatImportPart.FeedData(ms);
    AltChunk altChunk = new AltChunk();
    altChunk.Id = htmlSectionID;

    mainDocumenPart.Document.Body.Append(altChunk);

    /*
     inch equiv = 1440 (1 inch margin)
     */
    double width = 8.5 * 1440;
    double height = 11 * 1440;

    SectionProperties sectionProps = new SectionProperties();
    PageSize pageSize;
    if (isLandScape)
    {
        pageSize = new PageSize() { Width = (UInt32Value)height, Height = (UInt32Value)width, Orient = PageOrientationValues.Landscape };
    }
    else
    {
        pageSize = new PageSize() { Width = (UInt32Value)width, Height = (UInt32Value)height, Orient = PageOrientationValues.Portrait };
    }

    rMargin = rMargin * 1440;
    lMargin = lMargin * 1440;
    bMargin = bMargin * 1440;
    tMargin = tMargin * 1440;

    PageMargin pageMargin = new PageMargin() { Top = (Int32)tMargin, Right = (UInt32Value)rMargin, Bottom = (Int32)bMargin, Left = (UInt32Value)lMargin, Header = (UInt32Value)360U, Footer = (UInt32Value)360U, Gutter = (UInt32Value)0U };

    sectionProps.Append(pageSize);
    sectionProps.Append(pageMargin);
    mainDocumenPart.Document.Body.Append(sectionProps);

    //Saving/Disposing of the created word Document
    document.MainDocumentPart.Document.Save();
    document.Dispose();
}

In searching, I found this code:

SpacingBetweenLines spacing = new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" };

I've placed it many places in my function, but I can't seem to find the correct place to Append this setting.

I worked on the function trying to set the spacing in code, but wasn't able to remove the spacing. I decided to try creating a Template Word Document and setting the spacing in that document.

I copy the template.docx file, creating the one I will use, then use the adjusted function below to add the HTML string:

private static void SaveDOCX(string fileName, string BodyText, bool isLandScape, double rMargin, double lMargin, double bMargin, double tMargin)
{
    WordprocessingDocument document = WordprocessingDocument.Open(fileName, true);
    MainDocumentPart mainDocumenPart = document.MainDocumentPart;

    //Place the HTML String into a MemoryStream Object
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body>" + BodyText + "</body></html>"));

    //Assign an HTML Section for the String Text
    string htmlSectionID = "Sect1";

    // Create alternative format import part.
    AlternativeFormatImportPart formatImportPart = mainDocumenPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, htmlSectionID);

    // Feed HTML data into format import part (chunk).
    formatImportPart.FeedData(ms);
    AltChunk altChunk = new AltChunk();
    altChunk.Id = htmlSectionID;

    //Clear out the Document Body and Insert just the HTML string.  (This prevents an empty First Line)
    mainDocumenPart.Document.Body.RemoveAllChildren();
    mainDocumenPart.Document.Body.Append(altChunk);

    /*
     Set the Page Orientation and Margins Based on Page Size
     inch equiv = 1440 (1 inch margin)
     */
    double width = 8.5 * 1440;
    double height = 11 * 1440;

    SectionProperties sectionProps = new SectionProperties();
    PageSize pageSize;
    if (isLandScape)
        pageSize = new PageSize() { Width = (UInt32Value)height, Height = (UInt32Value)width, Orient = PageOrientationValues.Landscape };
    else
        pageSize = new PageSize() { Width = (UInt32Value)width, Height = (UInt32Value)height, Orient = PageOrientationValues.Portrait };

    rMargin = rMargin * 1440;
    lMargin = lMargin * 1440;
    bMargin = bMargin * 1440;
    tMargin = tMargin * 1440;

    PageMargin pageMargin = new PageMargin() { Top = (Int32)tMargin, Right = (UInt32Value)rMargin, Bottom = (Int32)bMargin, Left = (UInt32Value)lMargin, Header = (UInt32Value)360U, Footer = (UInt32Value)360U, Gutter = (UInt32Value)0U };

    sectionProps.Append(pageSize);
    sectionProps.Append(pageMargin);
    mainDocumenPart.Document.Body.Append(sectionProps);

    //Saving/Disposing of the created word Document
    document.MainDocumentPart.Document.Save();
    document.Dispose();
}

By using the template file, the line spacing is correct.

For those that might find this function useful, here is the code that calls the function:

string filePath = "~/Content/Exports/Temp/";

string WordTemplateFile = HttpContext.Current.Server.MapPath("/Content/Templates/WordTemplate.docx");
string DestinationPath = HttpContext.Current.Server.MapPath(filePath);
string NewFileName = DOCXFileName + ".docx";

string destFile = System.IO.Path.Combine(DestinationPath, NewFileName);

System.IO.File.Copy(WordTemplateFile, destFile, true);

SaveDOCX(destFile, HTMLString, isLandScape, rMargin, lMargin, bMargin, tMargin);

You can't change the formatting because your code is only inserting HTML into a Word doc. To change the formatting, the HTML text needs to be converted to regular text and added to the Word doc as such. I was in a similar issue and using the HtmlToOpenXml library makes this quick and simple.

using HtmlToOpenXml;

Then the function:

    protected virtual void createWord()
    {
        string html = "*myHtml*";

        // Create WordProcessingDocument
        WordprocessingDocument doc = WordprocessingDocument.Create(ms, WordprocessingDocumentType.Document);
        MainDocumentPart mainPart = doc.MainDocumentPart;
        if (mainPart == null)
            mainPart = doc.AddMainDocumentPart();

        Document document = doc.MainDocumentPart.Document;
        if (document == null)
            document = mainPart.Document = new Document();

        Body body = mainPart.Document.Body;
        if (body == null)
            body = mainPart.Document.Body = new Body(new SectionProperties(new PageMargin() { Top = 1440, Right = 1440U, Bottom = 1440, Left = 1440U, Header = 720U, Footer = 720U, Gutter = 0U }));

        // Convert Html to OpenXml
        HtmlConverter converter = new HtmlConverter(mainPart);
        converter.ParseHtml(html);

        // Reformat paragraphs
        ParagraphProperties pProps = new ParagraphProperties(new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" });
        var paragraphs = doc.MainDocumentPart.Document.Body.Descendants<Paragraph>().ToList();
        foreach (Paragraph p in paragraphs)
        {
            if (p != null)
                p.PrependChild(pProps.CloneNode(true));
        }

        // Close the document handle
        doc.Close();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM