0

我目前正在研究 MailMerge Word-doc。它部分用字符串填充,部分用html(可以包含表格、图片、粗体/斜体/下划线文本等)填充。与默认单词对齐方式相比,单词 doc 还具有自定义对齐方式(因此标尺left, top, right, bottom类似于1.5, 0.3, 0.3, 0.3我的 MailMerge word-doc 中的内容,而 word-default 类似于2.5, 2.5, 2.5, 2.5.)

现在的问题是InsertHtml跳转(并且似乎遵循默认的单词对齐,而不是我们的自定义对齐),而不是由 word-doc 中存在的静态文本和表格对齐。

我知道 MailMerging 使用默认的 MS Word 函数来插入 html,所以问题可能在于该默认函数而不是 Apose 的 MailMerging。我只是想知道是否有人知道解决方案。

这是结果的外观示例。我已经将标尺包括在标尺上X设置的位置以进行对齐。假设我们在 HTML 部分插入的文本是非常基本的,例如纯文本:“这是一个测试 HTML 文本”。Word-doc 模板如下所示:

+ . 2 . | X 1 ............................................... 17 . | . X . |
X         *Start of a table*
.         ...
.         Value:       |     {{Value}}
.         *End of the table*
.
.         *A bold title*
.
.         {{html_Text}}
.
.         *Another bold title*
.
X
29
+

但是 MailMerging 之后的结果是这样的:

+ . 2 . | X 1 ............................................... 17 . | . X . |
X         *Start of a table*
.         ...
.         Value:       |     2500
.         *End of the table*
.
.         *A bold title*
.
.                  this is a test HTML text
.
.         *Another bold title*
.
X
29
+

html 文本在默认的 Word 标尺下不正确地对齐,而不是该文档的自定义之一。

(PS:我知道带括号的 MailMerging{{Something}}比 使用少<<Something>>,但两者的工作原理相同。我曾有人质疑我们过去使用的 MailMerge 语法,因此请注意。)


这是我们.NET项目中的相关代码:

打印 DTO 对象:

public class OurObjectPrintDto
{
    public OurObjectPrintDto(OurObject ob)
    {
        ...
        Value = ob.Value;

        ...

        html_Text = ob.Text;
    }

    public string Value { get; private set; }
    public string html_Text { get; private set; }
}

当我们点击 Generate Document 按钮时的方法:

[HttpGet]
public ActionResult Print(Guid id)
{
    var ourObject = NhSession.GetByGuid<OurObject>(id);
    var printData = new OutObjectPrintDto(ourObject);

    var documentAsByteArray = _documentService.CreateMyObjectPrintAsBytes(printData);

    return File(documentAsByteArray, "application/pdf");
}

CreateMyObjectPrintAsBytes-方法:

public byte[] CreateMyObjectPrintAsBytes(MyObject printData)
{
    return GenerateDocument("myobject.docx", printData);
}

private byte[] GenerateDocument(string fileName, object printData)
{
    if (printData == null) throw new ArgumentNullException("printData");

    var path = Path.Combine(_templatePath, fileName);

    using (var fileStream = new File.OpenRead(path))
    {
        var dataSource = new DocumentDataSource(printData);
        return DocumentConverter.GenerateDocument(fileStream, dataSource);
    }
}

DocumentConvert.GenerateDocument-方法:

public byte[] GenerateDocument(Stream template, DocumentDataSource dataSource)
{
    var doc = new Document(template);

    doc.MailMerge.UseNonMergeFields = true;
    doc.MailMerge.CleanupOptions = MailMergeCleanupOption.RemoveContainingFields |
                                   MailMergeCleanupOptions.RemoveUnusedFields |
                                   MailMergeCleanupOptions.RemoveUnusedRegions |
                                   MailMergeCleanupOptions.RemoveEmptyParagraphs;
    doc.ResourceLoadingCallback = new ImageLoadingHandler();

    // Support html MailMerge-fields
    doc.MailMerge.FieldMergingCallback = new HandleMergeFieldInsertHtml();

    doc.MailMerge.Execute(dataSource);
    doc.MailMerge.ExecuteWithRegions((IMailMergeDataSourceRoot) dataSource);

    doc.UpdateFields();

    using (var memoryStream = new MemoryStream())
    {
        doc.Save(memoryStream, SaveFormat.Pdf);
        return memoryStream.ToArray();
    }
}

HandleMailMergeFieldInsertHtml-班级:

using Aspose.Words;
using Aspose.Words.Reporting;

namespace Sogyo.Util.Pdf
{
    public class HandleMergeFieldInsertHtml : IFieldMergingCallback
    {
        // This is called when merge field is atually merged with data in the document
        void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
        {
            // All merge field that expect HTML data should be marked with the prefix 'html_'
            if (e.DocumentFieldName.StartsWith("html_") && e.FieldValue != null)
            {
                // Insert the text for this merge field as HTML data
                var documentBuilder = new DocumentBuilder(e.Document);
                documentBuilder.MoveToMergeField(e.DocumentFieldName);
                documentBuilder.InsertHtml((string) e.FieldValue);

                // The HTML text itself should not be inserted.
                // We have already inserted it as an HTML.
                e.Text = "";
            }
        }

        void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
        {
        }
    }
}

我确实尝试在代码中设置documentBuilder's.PageSetup.LeftMargin来更改文档的标尺。这确实改变了文档的标尺对齐方式,但是插入的 html 文本仍然以相同的量跳入,就好像一个制表符在它之前一样。

4

1 回答 1

0

好的,问题已解决。作为测试,我尝试将输出临时更改为,.docx而不是.pdf,因此我可以更好地查看转换后的文档中的选项卡等:

doc.Save(memoryStream, SaveFormat.Pdf);
// changed to
doc.Save(memoryStream, SaveFormat.Docx);

return File(documentAsByteArray, "application/pdf");
// changed to
return File(documentAsByteArray, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

当我打开转换后的文件时,.docx我很快就发现了这个问题。它与 MailMerging 无关,而是与文档本身的标尺有关。Word-doc 标尺既有灰色部分,也有沙漏式的东西(X在我的问题中)。

它被设置为:在此处输入图像描述

而不是这个:在此处输入图像描述

在将我的 Word 文档中的沙漏和灰色部分相互对齐后,在 MailMerging 之后,html 文本也与其余部分正确对齐。

于 2016-01-13T13:06:51.233 回答