using System;
#if __MACOS__
using Syncfusion.Drawing;
#else
using System.Drawing;
#endif
using System.Linq;
using Syncfusion.DocIO.DLS;
using Vinno.IUS.Common.Log;
using Vinno.vCloud.Report.Interfaces;
using Vinno.vCloud.Report.Models;
using PageNumberStyle = Syncfusion.DocIO.DLS.PageNumberStyle;
namespace Vinno.vCloud.ReportGenerator
{
public class ReportWordDocument : WordDocument, IReportWordDocument
{
}
public class ReportWordDocumentManager
{
private static bool _showImageIndex;
private static float _widthZoomRatio;
///
/// gets word document from report info
///
///
///
public static IReportWordDocument GetGenerateWordDocument(ReportInfo reportInfo)
{
_widthZoomRatio = 1;
var wordDocument = new ReportWordDocument();
try
{
if (reportInfo == null)
{
return null;
}
_showImageIndex = reportInfo.ElementValues != null && reportInfo.ElementValues.ContainsKey(ElementTag.AIIndexFlag);
reportInfo = reportInfo.Clone();//bcs may del table row or change HeaderDistance/HeaderHeight
var reportTemplate = reportInfo.Template;
var headerVisible = reportTemplate.Header.Any(x => x.IsVisibleIn(reportInfo));
if (!headerVisible)
reportInfo.Template.HeaderDistance = 0;
var footerVisible = reportTemplate.Footer.Any(x => x.IsVisibleIn(reportInfo));
if (!footerVisible)
reportInfo.Template.FooterDistance = 0;
if (reportTemplate.InvertColor)
{
wordDocument.Background.Type = BackgroundType.Color;
wordDocument.Background.Color = Color.Black;
}
wordDocument.FontSettings.SubstituteFont += OnSubstituteFont;
var section = wordDocument.AddSection();
SetPageSetting(reportTemplate.PageSize, reportTemplate.PagePadding, section);
if (reportTemplate.Header.Count > 0)
{
if (reportTemplate.HeaderHeight == null)
{
foreach (var blockElement in reportTemplate.Header)
{
AddBlock(reportInfo, blockElement, section.HeadersFooters.Header, wordDocument);
}
}
else
{
var table = section.HeadersFooters.Header.AddTable();
InitTable(table);
var cell = table.Rows[0].Cells[0];
foreach (var blockElement in reportTemplate.Header)
{
AddBlock(reportInfo, blockElement, cell, wordDocument);
}
//bcs may del table row in AddBlock
table.Rows[0].Height = (float)reportTemplate.HeaderHeight - 5;
}
}
foreach (var blockElement in reportTemplate.Blocks)
{
AddBlock(reportInfo, blockElement, section.Body, wordDocument);
}
if (reportTemplate.Footer.Count > 0)
{
if (reportTemplate.FooterHeight == null)
{
foreach (var blockElement in reportTemplate.Footer)
{
AddBlock(reportInfo, blockElement, section.HeadersFooters.Footer, wordDocument);
}
}
else
{
var table = section.HeadersFooters.Footer.AddTable();
InitTable(table);
table.Rows[0].Height = (float)reportTemplate.FooterHeight - 5;
var cell = table.Rows[0].Cells[0];
foreach (var blockElement in reportTemplate.Footer)
{
AddBlock(reportInfo, blockElement, cell, wordDocument);
}
}
}
var pageNumberElement = reportTemplate.Footer.SelectMany(f => f.Elements)
.FirstOrDefault(e => e is PageNumberElement) as PageNumberElement;
if (pageNumberElement != null)
{
section.PageSetup.RestartPageNumbering = true;
section.PageSetup.PageStartingNumber = 1;
section.PageSetup.PageNumberStyle = PageNumberStyle.Arabic;
}
foreach (WSection wSection in wordDocument.Sections)
{
wSection.PageSetup.HeaderDistance = (float)reportInfo.Template.HeaderDistance;
if (!headerVisible)
{
wSection.HeadersFooters.Header.ChildEntities.Clear();
}
wSection.PageSetup.FooterDistance = (float)reportInfo.Template.FooterDistance;
if (!footerVisible)
{
wSection.HeadersFooters.Footer.ChildEntities.Clear();
}
var endParagraph = wSection.AddParagraph();//hide blank page/paragraph after last table
endParagraph.BreakCharacterFormat.FontSize = 0;
}
}
catch (Exception e)
{
Logger.WriteLineError($"Generate word document error {e}");
}
return wordDocument;
}
public static IReportWordDocument GetGenerateWordDocumentAdaptPageSetting(ReportInfo reportInfo, RTPageSize pageSize, RTThickness pagePadding)
{
var wordDocument = new ReportWordDocument();
try
{
if (reportInfo == null)
{
return null;
}
_showImageIndex = reportInfo.ElementValues != null && reportInfo.ElementValues.ContainsKey(ElementTag.AIIndexFlag);
reportInfo = reportInfo.Clone();//bcs may del table row or change HeaderDistance/HeaderHeight
var reportTemplate = reportInfo.Template;
_widthZoomRatio = (float)Math.Round((pageSize.Width-pagePadding.Left-pagePadding.Right) / (reportTemplate.PageSize.Width-reportTemplate.PagePadding.Left-reportTemplate.PagePadding.Right), 3);
var headerVisible = reportTemplate.Header.Any(x => x.IsVisibleIn(reportInfo));
if (!headerVisible)
reportInfo.Template.HeaderDistance = 0;
var footerVisible = reportTemplate.Footer.Any(x => x.IsVisibleIn(reportInfo));
if (!footerVisible)
reportInfo.Template.FooterDistance = 0;
if (reportTemplate.InvertColor)
{
wordDocument.Background.Type = BackgroundType.Color;
wordDocument.Background.Color = Color.Black;
}
wordDocument.FontSettings.SubstituteFont += OnSubstituteFont;
var section = wordDocument.AddSection();
SetPageSetting(pageSize, pagePadding, section);
if (reportTemplate.Header.Count > 0)
{
if (reportTemplate.HeaderHeight == null)
{
foreach (var blockElement in reportTemplate.Header)
{
AddBlock(reportInfo, blockElement, section.HeadersFooters.Header, wordDocument);
}
}
else
{
var table = section.HeadersFooters.Header.AddTable();
InitTable(table);
var cell = table.Rows[0].Cells[0];
foreach (var blockElement in reportTemplate.Header)
{
AddBlock(reportInfo, blockElement, cell, wordDocument);
}
//bcs may del table row in AddBlock
table.Rows[0].Height = (float)reportTemplate.HeaderHeight - 5;
}
}
foreach (var blockElement in reportTemplate.Blocks)
{
AddBlock(reportInfo, blockElement, section.Body, wordDocument);
}
if (reportTemplate.Footer.Count > 0)
{
if (reportTemplate.FooterHeight == null)
{
foreach (var blockElement in reportTemplate.Footer)
{
AddBlock(reportInfo, blockElement, section.HeadersFooters.Footer, wordDocument);
}
}
else
{
var table = section.HeadersFooters.Footer.AddTable();
InitTable(table);
table.Rows[0].Height = (float)reportTemplate.FooterHeight - 5;
var cell = table.Rows[0].Cells[0];
foreach (var blockElement in reportTemplate.Footer)
{
AddBlock(reportInfo, blockElement, cell, wordDocument);
}
}
}
var pageNumberElement = reportTemplate.Footer.SelectMany(f => f.Elements)
.FirstOrDefault(e => e is PageNumberElement) as PageNumberElement;
if (pageNumberElement != null)
{
section.PageSetup.RestartPageNumbering = true;
section.PageSetup.PageStartingNumber = 1;
section.PageSetup.PageNumberStyle = PageNumberStyle.Arabic;
}
foreach (WSection wSection in wordDocument.Sections)
{
wSection.PageSetup.HeaderDistance = (float)reportInfo.Template.HeaderDistance;
if (!headerVisible)
{
wSection.HeadersFooters.Header.ChildEntities.Clear();
}
wSection.PageSetup.FooterDistance = (float)reportInfo.Template.FooterDistance;
if (!footerVisible)
{
wSection.HeadersFooters.Footer.ChildEntities.Clear();
}
var endParagraph = wSection.AddParagraph();//hide blank page/paragraph after last table
endParagraph.BreakCharacterFormat.FontSize = 0;
}
}
catch (Exception e)
{
Logger.WriteLineError($"Generate word document error {e}");
}
return wordDocument;
}
private static void OnSubstituteFont(object sender, SubstituteFontEventArgs args)
{
args.AlternateFontName = "Microsoft YaHei";
}
private static void InitTable(IWTable table)
{
table.ResetCells(1, 1);
table.Rows[0].HeightType = TableRowHeightType.Exactly;
table.TableFormat.Borders.BorderType = BorderStyle.None;
table.TableFormat.Paddings.All = 0;// workaround for syncfusion bug
}
///
/// Add Block
///
public static void AddBlock(ReportInfo reportInfo, IBlockElement blockElement, WTextBody textBody, ReportWordDocument wordDocument)
{
if (blockElement is Paragraph paragraph)
{
ParagraphGenerater.Generate(reportInfo, paragraph, textBody);
return;
}
if (blockElement is RTTable rtTable)
{
if (rtTable.IsVisibleIn(reportInfo))
{
TableGenerater.Generate(reportInfo, rtTable, textBody, _widthZoomRatio, true);
return;
}
if (reportInfo.Template.HeaderHeight != null && textBody.IsInHeader())
reportInfo.Template.HeaderHeight -= rtTable.RowDefinitions.Sum(x => x.Height);
}
if (blockElement is InputImageList inputImageList)
{
TableGenerater.GenerateInputImageList(reportInfo, inputImageList, textBody, _showImageIndex);
}
if (blockElement is AtlasElement atlasElement)
{
TableGenerater.GenerateAtlasElement(reportInfo, atlasElement, textBody, wordDocument);
}
}
///
/// Set pagesetting
///
private static void SetPageSetting(RTPageSize pageSize, RTThickness pagePadding, IWSection section)
{
// workaround fix for too large page size crash
var width = (float)pageSize.Width;
if (width > 3000)
width = 3000;
var height = (float)pageSize.Height;
if (height > 3000)
height = 3000;
section.PageSetup.PageSize = new SizeF(width, height);
section.PageSetup.Margins = new MarginsF((float)pagePadding.Left,
(float)pagePadding.Top, (float)pagePadding.Right,
(float)pagePadding.Bottom);
}
}
}