MailMerge InsertHtml следует выравниванию Word-документа
В настоящее время я работаю над Word-документом MailMerge. Он частично заполнен строками, а частично HTML (который может содержать таблицы, рисунки, полужирный / курсив / подчеркнутый текст и т. Д.). Слово doc также имеет пользовательское выравнивание по сравнению с выравниванием слов по умолчанию (поэтому линейка для left, top, right, bottom
это что-то вроде 1.5, 0.3, 0.3, 0.3
в моем MailMerge Word-документ, в то время как слово по умолчанию это что-то вроде 2.5, 2.5, 2.5, 2.5
.)
Теперь проблема в том, что InsertHtml
включается (и, кажется, следует выравниванию слов по умолчанию вместо нашего обычного) вместо выравнивания по статическому тексту и таблицам, присутствующим в word-doc.
Я знаю, что MailMerging использует функции MS Word по умолчанию для вставки html, поэтому, возможно, проблема заключается в функции по умолчанию, а не в MailMerging Apose. Мне просто интересно, если кто-то знает решение.
Вот наглядный пример того, как выглядит результат. Я включил линейку где 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; }
}
Метод, когда мы нажимаем кнопку "Создать документ":
[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-текст все равно появляется на ту же величину, как если бы перед ним была вкладка или что-то еще.
1 ответ
Хорошо, проблема исправлена. В качестве теста я попытался временно изменить выход на .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 поверх друг друга, HTML-текст также корректно выравнивается с остальными после MailMerging.