简体   繁体   English

C# 打开 XML HTML 到 DOCX 间距

[英]C# Open XML HTML to DOCX Spacing

I've been working on my site, and trying to create an Export to Word.我一直在我的网站上工作,并试图创建一个导出到 Word。 The export works well, converting HTML string to DOCX.导出效果很好,将 HTML 字符串转换为 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.默认情况下,Word 添加 8pt Spacing After 并将行间距设置为两倍。 I would prefer 0 and Single.我更喜欢 0 和 Single。

Here is the Function I created to Save a Word Document:这是我创建的用于保存 Word 文档的函数:

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.我决定尝试创建一个模板 Word 文档并在该文档中设置间距。

I copy the template.docx file, creating the one I will use, then use the adjusted function below to add the HTML string:我复制 template.docx 文件,创建我将使用的文件,然后使用下面调整后的函数添加 HTML 字符串:

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.您无法更改格式,因为您的代码只是将 HTML 插入到 Word 文档中。 To change the formatting, the HTML text needs to be converted to regular text and added to the Word doc as such.要更改格式,需要将 HTML 文本转换为常规文本并添加到 Word 文档中。 I was in a similar issue and using the HtmlToOpenXml library makes this quick and simple.我遇到了类似的问题,使用 HtmlToOpenXml 库使这变得快速而简单。

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();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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