123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- 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;
- /// <summary>
- /// gets word document from report info
- /// </summary>
- /// <param name="reportInfo"></param>
- /// <returns></returns>
- 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
- }
- /// <summary>
- /// Add Block
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// Set pagesetting
- /// </summary>
- 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);
- }
- }
- }
|