Using Aspose.Words 13.2.0.0
Code from a sample console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aspose.Words;
using System.IO;
using System.Text.RegularExpressions;
using AsposeCoverLetter;
namespace ConsoleAspose
{
public class AsposeCoverLetter
{
public void DoWork()
{
Document template = new Document(this.GetType().Assembly.GetManifestResourceStream("ConsoleAspose.Template.docx"));
TemplateDataSourceDTO ds = DefineDataSource();
string hpCoverLetterName = "My Health Plan";
string hpName = hpCoverLetterName;
MailMerge(ds, template, hpCoverLetterName, hpName, true, false);
}
private Document MailMerge(TemplateDataSourceDTO dataSource, Document documentTemplate, string hpCoverLetterName, string hpName, bool isViewOnly, bool isFromTemplateMaintenancePreview)
{
if (dataSource != null && documentTemplate != null && string.IsNullOrEmpty(hpCoverLetterName) == false && string.IsNullOrEmpty(hpName) == false)
{
License asposeWordsLicense = new License();
asposeWordsLicense.SetLicense("Aspose.Words.lic");
// do the full merge with the template as is
Document mergedFullDocument = documentTemplate.Clone();
mergedFullDocument.MailMerge.Execute(dataSource);
OutputDocs(" initial merge as is ", mergedFullDocument, dataSource, documentTemplate);
if (isFromTemplateMaintenancePreview == true || dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString()) == true)
{
// Determine if the template already contains a cover letter.
bool mergedFullDocumentContainsCoverLetter = false;
string address = dataSource[AuthLetterTemplateBusiness.FieldName.MemberStreetAddress.ToString()];
string cityStateZip = dataSource[AuthLetterTemplateBusiness.FieldName.MemberCityStateZip.ToString()];
if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(cityStateZip))
{
throw new Exception("Missing address and/or city state zip in Letter Gen mail merge");
}
Regex regAddress = new Regex(address, RegexOptions.None);
Regex regCityStateZip = new Regex(cityStateZip, RegexOptions.None);
DocumentPageSplitter splitterDocCopy = new DocumentPageSplitter(mergedFullDocument);
// mergedPartialDocument now contains the first 2 pages of the mergedFullDocument document
Document mergedPartialDocument = splitterDocCopy.GetDocumentOfPageRange(1, 2); // startIndex and endIndex are 1-based!
// looking for at least 2 instances: cover is 1, first page would be the 2nd
if (mergedPartialDocument.Range.Replace(regAddress, address) >= 2 && mergedPartialDocument.Range.Replace(regCityStateZip, cityStateZip) >= 2)
{
// yes, mergedPartialDocument has a cover page with member address embeded
mergedFullDocumentContainsCoverLetter = true;
// set mergedPartialDocument to page 2 and on.... essentially removes the cover page that's built into the template
//mergedPartialDocument = splitterDocCopy.GetDocumentOfPageRange(2, mergedFullDocument.PageCount).Clone();
mergedPartialDocument = splitterDocCopy.GetDocumentOfPageRange(2, mergedFullDocument.PageCount);
OutputDocs(" cover page removed", mergedPartialDocument, dataSource, documentTemplate);
}
Document coverLetter;
string coverLetterOverrideSalutation = null;
if (isFromTemplateMaintenancePreview == true
||
(string.IsNullOrEmpty(dataSource[AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString()]) == true
|| dataSource[AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString()].ToLower() == "unknown"))
{
// this has NOT been merged with a fixed cover letter
coverLetterOverrideSalutation = null;
}
else
{
// this has been merged with a fixed cover letter before
coverLetterOverrideSalutation = (isViewOnly == true ? dataSource[AuthLetterTemplateBusiness.FieldName.CoverLetterMemberTo.ToString()] : null);
}
coverLetter = GetCoverLetter(dataSource, hpCoverLetterName, hpName, coverLetterOverrideSalutation);
// adding .Clone() at the end does't fix everything
//coverLetter = GetCoverLetter(dataSource, hpCoverLetterName, hpName, coverLetterOverrideSalutation).Clone();
// try adding .Clone() with AppendDocument to coverLetter directly - no effect, font is still decreased
//coverLetter = GetCoverLetter(dataSource, hpCoverLetterName, hpName, coverLetterOverrideSalutation).Clone();
// Create a new combined document and start with adding the cover letter
//Document combinedDocument = new Document();
//combinedDocument.RemoveAllChildren();
//coverLetter.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;
//combinedDocument.AppendDocument(coverLetter, ImportFormatMode.KeepSourceFormatting);
// now append to the combined document whatever is appropriate.
if (mergedFullDocumentContainsCoverLetter == true)
{
// combine with mergedPartialDocument that no longer contains the cover page (it was removed above)
mergedPartialDocument.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;
// as is
//combinedDocument.AppendDocument(mergedPartialDocument, ImportFormatMode.KeepSourceFormatting);
// try AppendDocument to coverLetter directly
coverLetter.AppendDocument(mergedPartialDocument, ImportFormatMode.KeepSourceFormatting);
// try AppendDocument to coverLetter directly - with ImportFormatMode.UseDestinationStyles
//coverLetter.AppendDocument(mergedPartialDocument, ImportFormatMode.UseDestinationStyles);
// *** Adding .Clone() doesn't fix it
//combinedDocument.AppendDocument(mergedPartialDocument.Clone(), ImportFormatMode.KeepSourceFormatting);
}
else
{
// combine with entire merged full document that doesn't contain a cover letter
mergedFullDocument.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;
// as is
//combinedDocument.AppendDocument(mergedFullDocument, ImportFormatMode.KeepSourceFormatting);
// try AppendDocument to coverLetter directly
coverLetter.AppendDocument(mergedFullDocument, ImportFormatMode.KeepSourceFormatting);
// try AppendDocument to coverLetter directly - with ImportFormatMode.UseDestinationStyles
//coverLetter.AppendDocument(mergedFullDocument, ImportFormatMode.UseDestinationStyles);
// *** Adding .Clone() doesn't fix it
//combinedDocument.AppendDocument(mergedFullDocument.Clone(), ImportFormatMode.KeepSourceFormatting);
}
// as is
//OutputDocs(null, combinedDocument, dataSource, documentTemplate);
//return combinedDocument;
// try AppendDocument to coverLetter directly
OutputDocs(" with replaced cover letter", coverLetter, dataSource, documentTemplate);
return coverLetter;
}
else
{
// generated/merged previously, before fixed cover page enhancement, return merged doc as as.
return mergedFullDocument;
}
}
return null;
}
private void OutputDocs(string addFileName, Document letter, TemplateDataSourceDTO dataSource, Document template)
{
string path = @"C:\Temp\Letter Gen INC\Output Letters\";
if (Directory.Exists(path) == false)
{
Directory.CreateDirectory(path);
}
string authNo = dataSource[AuthLetterTemplateBusiness.FieldName.AuthorizationNumber.ToString()];
string outputFile = null;
// output template only if doesn't already exist
outputFile = string.Format("{0}{1} Template.docx", path, authNo);
if (File.Exists(outputFile) == false)
{
template.Save(outputFile);
}
// output docx, delete first if already exists
outputFile = string.Format("{0}{1}{2}.docx", path, authNo, addFileName);
if (File.Exists(outputFile) == true)
{
File.Delete(outputFile);
}
letter.Save(outputFile);
// output pdf, delete first if already exists
outputFile = string.Format("{0}{1}{2}.pdf", path, authNo, addFileName);
if (File.Exists(outputFile) == true)
{
File.Delete(outputFile);
}
letter.Save(outputFile, SaveFormat.Pdf);
}
private Document GetCoverLetter(TemplateDataSourceDTO dataSource, string letterHPName, string hpName, string overrideSalutation)
{
Document coverLetter = null;
Document coverLetterTemplate = null;
if (dataSource != null)
{
coverLetterTemplate = new Document(this.GetType().Assembly.GetManifestResourceStream("ConsoleAspose.MHCAddress.docx"));
string mbrSalutation = null;
string mbrStreetAddress = null;
string mbrCityStateZip = null;
string mbrHealthPlan = null;
if (string.IsNullOrEmpty(overrideSalutation) == true)
{
if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.Salutation.ToString()))
{
mbrSalutation = dataSource[AuthLetterTemplateBusiness.FieldName.Salutation.ToString()];
}
else if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.BeneficiaryName.ToString()))
{
mbrSalutation = dataSource[AuthLetterTemplateBusiness.FieldName.BeneficiaryName.ToString()];
}
else if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.AddresseeName.ToString()))
{
mbrSalutation = dataSource[AuthLetterTemplateBusiness.FieldName.AddresseeName.ToString()];
}
else if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.MemberName.ToString()))
{
mbrSalutation = dataSource[AuthLetterTemplateBusiness.FieldName.MemberName.ToString()];
}
}
else
{
mbrSalutation = overrideSalutation;
}
if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.MemberStreetAddress.ToString()))
{
mbrStreetAddress = dataSource[AuthLetterTemplateBusiness.FieldName.MemberStreetAddress.ToString()];
}
if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.MemberCityStateZip.ToString()))
{
mbrCityStateZip = dataSource[AuthLetterTemplateBusiness.FieldName.MemberCityStateZip.ToString()];
}
mbrHealthPlan = letterHPName;
if (string.IsNullOrEmpty(mbrHealthPlan) || mbrHealthPlan.ToLower() == "unknown")
{
mbrHealthPlan = hpName;
}
if (string.IsNullOrEmpty(mbrHealthPlan) == false && string.IsNullOrEmpty(mbrSalutation) == false && string.IsNullOrEmpty(mbrStreetAddress) == false
&& string.IsNullOrEmpty(mbrCityStateZip) == false)
{
TemplateDataSourceDTO dsCover = new TemplateDataSourceDTO();
dsCover[AuthLetterTemplateBusiness.FieldName.MemberHealthPlan.ToString()] = mbrHealthPlan;
dsCover[AuthLetterTemplateBusiness.FieldName.Salutation.ToString()] = mbrSalutation;
dsCover[AuthLetterTemplateBusiness.FieldName.MemberStreetAddress.ToString()] = mbrStreetAddress;
dsCover[AuthLetterTemplateBusiness.FieldName.MemberCityStateZip.ToString()] = mbrCityStateZip;
//coverLetterTemplate.MailMerge.Execute(dsCover);
coverLetter = coverLetterTemplate.Clone();
coverLetter.MailMerge.Execute(dsCover);
if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString()) == true)
{
dataSource[AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString()] = mbrHealthPlan;
}
else
{
dataSource.Add(AuthLetterTemplateBusiness.FieldName.CoverLetterHealthPlan.ToString(), mbrHealthPlan);
}
if (dataSource.ContainsKey(AuthLetterTemplateBusiness.FieldName.CoverLetterMemberTo.ToString()) == true)
{
dataSource[AuthLetterTemplateBusiness.FieldName.CoverLetterMemberTo.ToString()] = mbrSalutation;
}
else
{
dataSource.Add(AuthLetterTemplateBusiness.FieldName.CoverLetterMemberTo.ToString(), mbrSalutation);
}
}
else
{
throw new Exception("One more missing member fields for Letter Gen cover letter");
}
}
return coverLetter;
}
private TemplateDataSourceDTO DefineDataSource()
{
TemplateDataSourceDTO ds = new TemplateDataSourceDTO();
ds.Add("DateToday", DateTime.Today.ToShortDateString());
ds.Add("BeneficiaryName", "TOE, HARRY");
ds.Add("MemberStreetAddress", "1234 MOCKINGBIRD LANE");
ds.Add("MemberCityStateZip", "GARDEN GROVE CA 92843");
ds.Add("DateToday, June 01", "2020]");
ds.Add("MemberID", "007123");
ds.Add("AuthorizationNumber", "PIPER1234");
ds.Add("RequestingProviderName", "DR.SAM GOTCHA");
ds.Add("ServiceRequested", "A Dermatology(skin specialist) Office Visit");
ds.Add("ClinicalReviewerSpecialty", "B.Smith, MD., Dermatology");
ds.Add("ClinicalReviewerSpecialty_Text", "B.Smith, MD., Dermatology");
ds.Add("ReasonsForDenial", "The information we received from your doctor does not support the need for this service.We cannot approve your request for a dermatology(skin specialist) office visit. We have reviewed the information provided.Your information states that you have dermatitis.This is swelling of the skin.You also have furuncle.This is a boil or painful swelling of the skin.The requested office visit is not medically necessary for your condition.The information does not show that your doctor can not care for your condition; you have failed standard treatment; or there is a question about your condition.As a result, the requested service has been denied.We based this decision on Monarch Healthcare Clinical Review Criteria- Dermatology Referral Guidelines.");
ds.Add("RecomendAltTreatment", "Instead of the service requested, we are recommending the following: please contact your primary care doctor for further evaluation, treatment and discussion of alternatives");
ds.Add("ServiceRequestedProviderName", "DR.JONATHAN FEELGOOD");
ds.Add("MemberPCP", "DR.SAM GOTCHA");
ds.Add("CoverLetterHealthPlan", "CareShore");
ds.Add("CoverLetterMemberTo", "TOE, HARRY");
ds.Add("ClinicalNoteDenialType", "Medical Necessity(CALO)");
ds.Add("ClinicalNoteDenialType_Text", "Medical Necessity(CALO)");
ds.Add("ClinicalNoteMedicalDirector", "Deanna Wasabi, MD");
ds.Add("ClinicalNoteMedicalDirector_Text", "Deanna Wasabi, MD");
return ds;
}
}
}