From 3d3bd531221a5cae6429a9b67fd654f837277182 Mon Sep 17 00:00:00 2001 From: vderyushev Date: Thu, 5 Dec 2024 08:31:46 +0300 Subject: [PATCH] Added new API 24.12 examples --- Examples/ApiExamples/ApiExamples/ExAI.cs | 19 +- Examples/ApiExamples/ApiExamples/ExCharts.cs | 140 ++++ Examples/ApiExamples/ApiExamples/ExLowCode.cs | 700 ++++++++++++++++++ .../ApiExamples/ApiExamples/ExMailMerge.cs | 30 + Examples/Data/Blank pages.docx | Bin 0 -> 18723 bytes Examples/Data/Mail merge tables.docx | Bin 0 -> 17395 bytes .../Mail merge with regions data set.docx | Bin 0 -> 7560 bytes Examples/Data/Mail merge with regions.docx | Bin 0 -> 7306 bytes Examples/Data/Mail merge.doc | Bin 0 -> 20992 bytes Examples/Data/Replace regex.docx | Bin 0 -> 7193 bytes Examples/Data/Report building.docx | Bin 0 -> 7177 bytes 11 files changed, 888 insertions(+), 1 deletion(-) create mode 100644 Examples/Data/Blank pages.docx create mode 100644 Examples/Data/Mail merge tables.docx create mode 100644 Examples/Data/Mail merge with regions data set.docx create mode 100644 Examples/Data/Mail merge with regions.docx create mode 100644 Examples/Data/Mail merge.doc create mode 100644 Examples/Data/Replace regex.docx create mode 100644 Examples/Data/Report building.docx diff --git a/Examples/ApiExamples/ApiExamples/ExAI.cs b/Examples/ApiExamples/ApiExamples/ExAI.cs index dc483700..d0dfbb57 100644 --- a/Examples/ApiExamples/ApiExamples/ExAI.cs +++ b/Examples/ApiExamples/ApiExamples/ExAI.cs @@ -5,7 +5,6 @@ // "as is", without warranty of any kind, either expressed or implied. ////////////////////////////////////////////////////////////////////////// -using System.Text; using NUnit.Framework; using Aspose.Words; using System; @@ -48,5 +47,23 @@ public void AiSummarize() multiDocumentSummary.Save(ArtifactsDir + "AI.AiSummarize.Multi.docx"); //ExEnd:AiSummarize } + + [Test, Ignore("This test should be run manually to manage API requests amount")] + public void AiTranslate() + { + //ExStart:AiTranslate + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:IAiModelText.Translate(Document, AI.Language) + //ExSummary:Shows how to translate text using Google models. + Document doc = new Document(MyDir + "Document.docx"); + + string apiKey = Environment.GetEnvironmentVariable("API_KEY"); + // Use Google generative language models. + IAiModelText model = (IAiModelText)AiModel.Create(AiModelType.Gemini15Flash).WithApiKey(apiKey); + + Document translatedDoc = model.Translate(doc, Language.Arabic); + translatedDoc.Save(ArtifactsDir + "AI.AiTranslate.docx"); + //ExEnd:AiTranslate + } } } diff --git a/Examples/ApiExamples/ApiExamples/ExCharts.cs b/Examples/ApiExamples/ApiExamples/ExCharts.cs index dc39a8f0..d4f3f142 100644 --- a/Examples/ApiExamples/ApiExamples/ExCharts.cs +++ b/Examples/ApiExamples/ApiExamples/ExCharts.cs @@ -2350,5 +2350,145 @@ public void FormatCode() Assert.AreEqual("#,##0.0#", seriesProperties.BubbleSizes.FormatCode); } } + + [Test] + public void DataLablePosition() + { + //ExStart:DataLablePosition + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ChartDataLabelCollection.Position + //ExFor:ChartDataLabel.Position + //ExFor:ChartDataLabelPosition + //ExSummary:Shows how to set the position of the data label. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + // Insert column chart. + Shape shape = builder.InsertChart(ChartType.Column, 432, 252); + Chart chart = shape.Chart; + ChartSeriesCollection seriesColl = chart.Series; + + // Delete default generated series. + seriesColl.Clear(); + + // Add series. + ChartSeries series = seriesColl.Add( + "Series 1", + new string[] { "Category 1", "Category 2", "Category 3" }, + new double[] { 4, 5, 6 }); + + // Show data labels and set font color. + series.HasDataLabels = true; + ChartDataLabelCollection dataLabels = series.DataLabels; + dataLabels.ShowValue = true; + dataLabels.Font.Color = Color.White; + + // Set data label position. + dataLabels.Position = ChartDataLabelPosition.InsideBase; + dataLabels[0].Position = ChartDataLabelPosition.OutsideEnd; + dataLabels[0].Font.Color = Color.DarkRed; + + doc.Save(ArtifactsDir + "Charts.LabelPosition.docx"); + //ExEnd:DataLablePosition + } + + [Test] + public void DoughnutChartLabelPosition() + { + //ExStart:DoughnutChartLabelPosition + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ChartDataLabel.Left + //ExFor:ChartDataLabel.LeftMode + //ExFor:ChartDataLabel.Top + //ExFor:ChartDataLabel.TopMode + //ExFor:ChartDataLabelLocationMode + //ExSummary:Shows how to place data labels of doughnut chart outside doughnut. + Document doc = new Document(); + DocumentBuilder builder = new DocumentBuilder(doc); + + const int chartWidth = 432; + const int chartHeight = 252; + Shape shape = builder.InsertChart(ChartType.Doughnut, chartWidth, chartHeight); + Chart chart = shape.Chart; + ChartSeriesCollection seriesColl = chart.Series; + // Delete default generated series. + seriesColl.Clear(); + + // Hide the legend. + chart.Legend.Position = LegendPosition.None; + + // Generate data. + const int dataLength = 20; + double totalValue = 0; + string[] categories = new string[dataLength]; + double[] values = new double[dataLength]; + for (int i = 0; i < dataLength; i++) + { + categories[i] = string.Format("Category {0}", i); + values[i] = dataLength - i; + totalValue += values[i]; + } + + ChartSeries series = seriesColl.Add("Series 1", categories, values); + series.HasDataLabels = true; + + ChartDataLabelCollection dataLabels = series.DataLabels; + dataLabels.ShowValue = true; + dataLabels.ShowLeaderLines = true; + + // The Position property cannot be used for doughnut charts. Let's place data labels using the Left and Top + // properties around a circle outside of the chart doughnut. + // The origin is in the upper left corner of the chart. + + const double titleAreaHeight = 25.5; // This can be calculated using title text and font. + const double doughnutCenterY = titleAreaHeight + (chartHeight - titleAreaHeight) / 2; + const double doughnutCenterX = chartWidth / 2d; + const double labelHeight = 16.5; // This can be calculated using label font. + const double oneCharLabelWidth = 12.75; // This can be calculated for each label using its text and font. + const double twoCharLabelWidth = 17.25; // This can be calculated for each label using its text and font. + const double yMargin = 0.75; + const double labelMargin = 1.5; + const double labelCircleRadius = chartHeight - doughnutCenterY - yMargin - labelHeight / 2; + + // Because the data points start at the top, the X coordinates used in the Left and Top properties of + // the data labels point to the right and the Y coordinates point down, the starting angle is -PI/2. + double totalAngle = -System.Math.PI / 2; + ChartDataLabel previousLabel = null; + + for (int i = 0; i < series.YValues.Count; i++) + { + ChartDataLabel dataLabel = dataLabels[i]; + + double value = series.YValues[i].DoubleValue; + double labelWidth = (value < 10) ? oneCharLabelWidth : twoCharLabelWidth; + double labelSegmentAngle = value / totalValue * 2 * System.Math.PI; + double labelAngle = labelSegmentAngle / 2 + totalAngle; + double labelCenterX = labelCircleRadius * System.Math.Cos(labelAngle) + doughnutCenterX; + double labelCenterY = labelCircleRadius * System.Math.Sin(labelAngle) + doughnutCenterY; + double labelLeft = labelCenterX - labelWidth / 2; + double labelTop = labelCenterY - labelHeight / 2; + + // If the current data label overlaps other labels, move it horizontally. + if ((previousLabel != null) && + (System.Math.Abs(previousLabel.Top - labelTop) < labelHeight) && + (System.Math.Abs(previousLabel.Left - labelLeft) < labelWidth)) + { + // Move right on the top, left on the bottom. + bool isOnTop = (totalAngle < 0) || (totalAngle >= System.Math.PI); + labelLeft = previousLabel.Left + labelWidth * (isOnTop ? 1 : -1) + labelMargin; + } + + dataLabel.Left = labelLeft; + dataLabel.LeftMode = ChartDataLabelLocationMode.Absolute; + dataLabel.Top = labelTop; + dataLabel.TopMode = ChartDataLabelLocationMode.Absolute; + + totalAngle += labelSegmentAngle; + previousLabel = dataLabel; + } + + doc.Save(ArtifactsDir + "Charts.DoughnutChartLabelPosition.docx"); + //ExEnd:DoughnutChartLabelPosition + } } } diff --git a/Examples/ApiExamples/ApiExamples/ExLowCode.cs b/Examples/ApiExamples/ApiExamples/ExLowCode.cs index 4210a01e..d2ab7b0d 100644 --- a/Examples/ApiExamples/ApiExamples/ExLowCode.cs +++ b/Examples/ApiExamples/ApiExamples/ExLowCode.cs @@ -5,7 +5,9 @@ // "as is", without warranty of any kind, either expressed or implied. ////////////////////////////////////////////////////////////////////////// +using System; using System.Collections.Generic; +using System.Data; using System.Drawing; using System.IO; using System.Linq; @@ -13,7 +15,13 @@ using Aspose.Page.XPS; using Aspose.Page.XPS.XpsModel; using Aspose.Words; +using Aspose.Words.Comparing; using Aspose.Words.LowCode; +using Aspose.Words.LowCode.MailMerging; +using Aspose.Words.LowCode.Reporting; +using Aspose.Words.LowCode.Splitting; +using Aspose.Words.Replacing; +using Aspose.Words.Reporting; using Aspose.Words.Saving; using NUnit.Framework; using LoadOptions = Aspose.Words.Loading.LoadOptions; @@ -341,5 +349,697 @@ private static void AssertXpsText(XpsElement element) if (element is XpsGlyphs) Assert.True(new[] { "Heading 1", "Head", "ing 1" }.Any(c => ((XpsGlyphs)element).UnicodeString.Contains(c))); } + + [Test] + public void CompareDocuments() + { + //ExStart:CompareDocuments + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Comparer.Compare(String, String, String, String, DateTime) + //ExFor:Comparer.Compare(String, String, String, SaveFormat, String, DateTime) + //ExFor:Comparer.Compare(String, String, String, String, DateTime, CompareOptions) + //ExFor:Comparer.Compare(String, String, String, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to simple compare documents. + // There is a several ways to compare documents: + string firstDoc = MyDir + "Table column bookmarks.docx"; + string secondDoc = MyDir + "Table column bookmarks.doc"; + + Comparer.Compare(firstDoc, secondDoc, ArtifactsDir + "LowCode.CompareDocuments.1.docx", "Author", new DateTime()); + Comparer.Compare(firstDoc, secondDoc, ArtifactsDir + "LowCode.CompareDocuments.2.docx", SaveFormat.Docx, "Author", new DateTime()); + Comparer.Compare(firstDoc, secondDoc, ArtifactsDir + "LowCode.CompareDocuments.3.docx", "Author", new DateTime(), new CompareOptions() { IgnoreCaseChanges = true }); + Comparer.Compare(firstDoc, secondDoc, ArtifactsDir + "LowCode.CompareDocuments.4.docx", SaveFormat.Docx, "Author", new DateTime(), new CompareOptions() { IgnoreCaseChanges = true }); + //ExEnd:CompareDocuments + } + + [Test] + public void CompareStreamDocuments() + { + //ExStart:CompareStreamDocuments + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Comparer.Compare(Stream, Stream, Stream, SaveFormat, String, DateTime) + //ExFor:Comparer.Compare(Stream, Stream, Stream, SaveFormat, String, DateTime, CompareOptions) + //ExSummary:Shows how to compare documents from the stream. + // There is a several ways to compare documents from the stream: + using (FileStream firstStreamIn = new FileStream(MyDir + "Table column bookmarks.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream secondStreamIn = new FileStream(MyDir + "Table column bookmarks.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.CompareStreamDocuments.1.docx", FileMode.Create, FileAccess.ReadWrite)) + Comparer.Compare(firstStreamIn, secondStreamIn, streamOut, SaveFormat.Docx, "Author", new DateTime()); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.CompareStreamDocuments.2.docx", FileMode.Create, FileAccess.ReadWrite)) + Comparer.Compare(firstStreamIn, secondStreamIn, streamOut, SaveFormat.Docx, "Author", new DateTime(), new CompareOptions() { IgnoreCaseChanges = true }); + } + } + //ExEnd:CompareStreamDocuments + } + + [Test] + public void MailMerge() + { + //ExStart:MailMerge + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(String, String, String[], Object[]) + //ExFor:MailMerger.Execute(String, String, SaveFormat, String[], Object[]) + //ExFor:MailMerger.Execute(String, String, SaveFormat, MailMergeOptions, String[], Object[]) + //ExSummary:Shows how to do mail merge operation for a single record. + // There is a several ways to do mail merge operation: + string doc = MyDir + "Mail merge.doc"; + + string[] fieldNames = new string[] { "FirstName", "Location", "SpecialCharsInName()" }; + string[] fieldValues = new string[] { "James Bond", "London", "Classified" }; + + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMerge.1.docx", fieldNames, fieldValues); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMerge.2.docx", SaveFormat.Docx, fieldNames, fieldValues); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMerge.3.docx", SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, fieldNames, fieldValues); + //ExEnd:MailMerge + } + + [Test] + public void MailMergeStream() + { + //ExStart:MailMergeStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, String[], Object[]) + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, MailMergeOptions, String[], Object[]) + //ExSummary:Shows how to do mail merge operation for a single record from the stream. + // There is a several ways to do mail merge operation using documents from the stream: + string[] fieldNames = new string[] { "FirstName", "Location", "SpecialCharsInName()" }; + string[] fieldValues = new string[] { "James Bond", "London", "Classified" }; + + using (FileStream streamIn = new FileStream(MyDir + "Mail merge.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStream.1.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, fieldNames, fieldValues); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStream.2.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, fieldNames, fieldValues); + } + //ExEnd:MailMergeStream + } + + [Test] + public void MailMergeDataRow() + { + //ExStart:MailMergeDataRow + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(String, String, DataRow) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataRow) + //ExFor:MailMerger.Execute(String, String, SaveFormat, MailMergeOptions, DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow. + // There is a several ways to do mail merge operation from a DataRow: + string doc = MyDir + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("Location"); + dataTable.Columns.Add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.Rows.Add(new string[] { "James Bond", "London", "Classified" }); + + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataRow.1.docx", dataRow); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataRow.2.docx", SaveFormat.Docx, dataRow); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataRow.3.docx", SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataRow); + //ExEnd:MailMergeDataRow + } + + [Test] + public void MailMergeStreamDataRow() + { + //ExStart:MailMergeStreamDataRow + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataRow) + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, MailMergeOptions, DataRow) + //ExSummary:Shows how to do mail merge operation from a DataRow using documents from the stream. + // There is a several ways to do mail merge operation from a DataRow using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("Location"); + dataTable.Columns.Add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.Rows.Add(new string[] { "James Bond", "London", "Classified" }); + + using (FileStream streamIn = new FileStream(MyDir + "Mail merge.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamDataRow.1.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, dataRow); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamDataRow.2.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataRow); + } + //ExEnd:MailMergeStreamDataRow + } + + [Test] + public void MailMergeDataTable() + { + //ExStart:MailMergeDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(String, String, DataTable) + //ExFor:MailMerger.Execute(String, String, SaveFormat, DataTable) + //ExFor:MailMerger.Execute(String, String, SaveFormat, MailMergeOptions, DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable. + // There is a several ways to do mail merge operation from a DataTable: + string doc = MyDir + "Mail merge.doc"; + + DataTable dataTable = new DataTable(); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("Location"); + dataTable.Columns.Add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.Rows.Add(new string[] { "James Bond", "London", "Classified" }); + + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataTable.1.docx", dataTable); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataTable.2.docx", SaveFormat.Docx, dataTable); + MailMerger.Execute(doc, ArtifactsDir + "LowCode.MailMergeDataTable.3.docx", SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataTable); + //ExEnd:MailMergeDataTable + } + + [Test] + public void MailMergeStreamDataTable() + { + //ExStart:MailMergeStreamDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, DataTable) + //ExFor:MailMerger.Execute(Stream, Stream, SaveFormat, MailMergeOptions, DataTable) + //ExSummary:Shows how to do mail merge operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable(); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("Location"); + dataTable.Columns.Add("SpecialCharsInName()"); + + DataRow dataRow = dataTable.Rows.Add(new string[] { "James Bond", "London", "Classified" }); + + using (FileStream streamIn = new FileStream(MyDir + "Mail merge.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeDataTable.1.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, dataTable); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeDataTable.2.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.Execute(streamIn, streamOut, SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataTable); + } + //ExEnd:MailMergeStreamDataTable + } + + [Test] + public void MailMergeWithRegionsDataTable() + { + //ExStart:MailMergeWithRegionsDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataTable) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataTable) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, MailMergeOptions, DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable. + // There is a several ways to do mail merge with regions operation from a DataTable: + string doc = MyDir + "Mail merge with regions.docx"; + + DataTable dataTable = new DataTable("MyTable"); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("LastName"); + dataTable.Rows.Add(new object[] { "John", "Doe" }); + dataTable.Rows.Add(new object[] { "", "" }); + dataTable.Rows.Add(new object[] { "Jane", "Doe" }); + + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataTable.1.docx", dataTable); + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataTable.2.docx", SaveFormat.Docx, dataTable); + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataTable.3.docx", SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataTable); + //ExEnd:MailMergeWithRegionsDataTable + } + + [Test] + public void MailMergeStreamWithRegionsDataTable() + { + //ExStart:MailMergeStreamWithRegionsDataTable + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataTable) + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, MailMergeOptions, DataTable) + //ExSummary:Shows how to do mail merge with regions operation from a DataTable using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataTable using documents from the stream: + DataTable dataTable = new DataTable("MyTable"); + dataTable.Columns.Add("FirstName"); + dataTable.Columns.Add("LastName"); + dataTable.Rows.Add(new object[] { "John", "Doe" }); + dataTable.Rows.Add(new object[] { "", "" }); + dataTable.Rows.Add(new object[] { "Jane", "Doe" }); + + using (FileStream streamIn = new FileStream(MyDir + "Mail merge.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.ExecuteWithRegions(streamIn, streamOut, SaveFormat.Docx, dataTable); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.ExecuteWithRegions(streamIn, streamOut, SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataTable); + } + //ExEnd:MailMergeStreamWithRegionsDataTable + } + + [Test] + public void MailMergeWithRegionsDataSet() + { + //ExStart:MailMergeWithRegionsDataSet + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(String, String, DataSet) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, DataSet) + //ExFor:MailMerger.ExecuteWithRegions(String, String, SaveFormat, MailMergeOptions, DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet. + // There is a several ways to do mail merge with regions operation from a DataSet: + string doc = MyDir + "Mail merge with regions data set.docx"; + + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.Columns.Add("CustomerID"); + tableCustomers.Columns.Add("CustomerName"); + tableCustomers.Rows.Add(new object[] { 1, "John Doe" }); + tableCustomers.Rows.Add(new object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.Columns.Add("CustomerID"); + tableOrders.Columns.Add("ItemName"); + tableOrders.Columns.Add("Quantity"); + tableOrders.Rows.Add(new object[] { 1, "Hawaiian", 2 }); + tableOrders.Rows.Add(new object[] { 2, "Pepperoni", 1 }); + tableOrders.Rows.Add(new object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.Tables.Add(tableCustomers); + dataSet.Tables.Add(tableOrders); + dataSet.Relations.Add(tableCustomers.Columns["CustomerID"], tableOrders.Columns["CustomerID"]); + + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataSet.1.docx", dataSet); + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataSet.2.docx", SaveFormat.Docx, dataSet); + MailMerger.ExecuteWithRegions(doc, ArtifactsDir + "LowCode.MailMergeWithRegionsDataSet.3.docx", SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataSet); + //ExEnd:MailMergeWithRegionsDataSet + } + + [Test] + public void MailMergeStreamWithRegionsDataSet() + { + //ExStart:MailMergeStreamWithRegionsDataSet + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, DataSet) + //ExFor:MailMerger.ExecuteWithRegions(Stream, Stream, SaveFormat, MailMergeOptions, DataSet) + //ExSummary:Shows how to do mail merge with regions operation from a DataSet using documents from the stream. + // There is a several ways to do mail merge with regions operation from a DataSet using documents from the stream: + DataTable tableCustomers = new DataTable("Customers"); + tableCustomers.Columns.Add("CustomerID"); + tableCustomers.Columns.Add("CustomerName"); + tableCustomers.Rows.Add(new object[] { 1, "John Doe" }); + tableCustomers.Rows.Add(new object[] { 2, "Jane Doe" }); + + DataTable tableOrders = new DataTable("Orders"); + tableOrders.Columns.Add("CustomerID"); + tableOrders.Columns.Add("ItemName"); + tableOrders.Columns.Add("Quantity"); + tableOrders.Rows.Add(new object[] { 1, "Hawaiian", 2 }); + tableOrders.Rows.Add(new object[] { 2, "Pepperoni", 1 }); + tableOrders.Rows.Add(new object[] { 2, "Chicago", 1 }); + + DataSet dataSet = new DataSet(); + dataSet.Tables.Add(tableCustomers); + dataSet.Tables.Add(tableOrders); + dataSet.Relations.Add(tableCustomers.Columns["CustomerID"], tableOrders.Columns["CustomerID"]); + + using (FileStream streamIn = new FileStream(MyDir + "Mail merge.doc", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamWithRegionsDataTable.1.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.ExecuteWithRegions(streamIn, streamOut, SaveFormat.Docx, dataSet); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.MailMergeStreamWithRegionsDataTable.2.docx", FileMode.Create, FileAccess.ReadWrite)) + MailMerger.ExecuteWithRegions(streamIn, streamOut, SaveFormat.Docx, new MailMergeOptions() { TrimWhitespaces = true }, dataSet); + } + //ExEnd:MailMergeStreamWithRegionsDataSet + } + + [Test] + public void Replace() + { + //ExStart:Replace + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(String, String, String, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, String, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document. + // There is a several ways to replace string in the document: + string doc = MyDir + "Footer.docx"; + string pattern = "(C)2006 Aspose Pty Ltd."; + string replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + Replacer.Replace(doc, ArtifactsDir + "LowCode.Replace.1.docx", pattern, replacement); + Replacer.Replace(doc, ArtifactsDir + "LowCode.Replace.2.docx", SaveFormat.Docx, pattern, replacement); + Replacer.Replace(doc, ArtifactsDir + "LowCode.Replace.3.docx", SaveFormat.Docx, pattern, replacement, new FindReplaceOptions() { FindWholeWordsOnly = false }); + //ExEnd:Replace + } + + [Test] + public void ReplaceStream() + { + //ExStart:ReplaceStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, String, String) + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, String, String, FindReplaceOptions) + //ExSummary:Shows how to replace string in the document using documents from the stream. + // There is a several ways to replace string in the document using documents from the stream: + string pattern = "(C)2006 Aspose Pty Ltd."; + string replacement = "Copyright (C) 2024 by Aspose Pty Ltd."; + + using (FileStream streamIn = new FileStream(MyDir + "Footer.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.ReplaceStream.1.docx", FileMode.Create, FileAccess.ReadWrite)) + Replacer.Replace(streamIn, streamOut, SaveFormat.Docx, pattern, replacement); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.ReplaceStream.2.docx", FileMode.Create, FileAccess.ReadWrite)) + Replacer.Replace(streamIn, streamOut, SaveFormat.Docx, pattern, replacement, new FindReplaceOptions() { FindWholeWordsOnly = false }); + } + //ExEnd:ReplaceStream + } + + [Test] + public void ReplaceRegex() + { + //ExStart:ReplaceRegex + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(String, String, Regex, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, Regex, String) + //ExFor:Replacer.Replace(String, String, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document. + // There is a several ways to replace string with regex in the document: + string doc = MyDir + "Footer.docx"; + Regex pattern = new Regex("gr(a|e)y"); + string replacement = "lavender"; + + Replacer.Replace(doc, ArtifactsDir + "LowCode.ReplaceRegex.1.docx", pattern, replacement); + Replacer.Replace(doc, ArtifactsDir + "LowCode.ReplaceRegex.2.docx", SaveFormat.Docx, pattern, replacement); + Replacer.Replace(doc, ArtifactsDir + "LowCode.ReplaceRegex.3.docx", SaveFormat.Docx, pattern, replacement, new FindReplaceOptions() { FindWholeWordsOnly = false }); + //ExEnd:ReplaceRegex + } + + [Test] + public void ReplaceStreamRegex() + { + //ExStart:ReplaceStreamRegex + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, Regex, String) + //ExFor:Replacer.Replace(Stream, Stream, SaveFormat, Regex, String, FindReplaceOptions) + //ExSummary:Shows how to replace string with regex in the document using documents from the stream. + // There is a several ways to replace string with regex in the document using documents from the stream: + Regex pattern = new Regex("gr(a|e)y"); + string replacement = "lavender"; + + using (FileStream streamIn = new FileStream(MyDir + "Replace regex.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.ReplaceStreamRegex.1.docx", FileMode.Create, FileAccess.ReadWrite)) + Replacer.Replace(streamIn, streamOut, SaveFormat.Docx, pattern, replacement); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.ReplaceStreamRegex.2.docx", FileMode.Create, FileAccess.ReadWrite)) + Replacer.Replace(streamIn, streamOut, SaveFormat.Docx, pattern, replacement, new FindReplaceOptions() { FindWholeWordsOnly = false }); + } + //ExEnd:ReplaceStreamRegex + } + + //ExStart:BuildReportData + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(String, String, Object) + //ExFor:ReportBuilder.BuildReport(String, String, Object, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data. + [Test] //ExSkip + public void BuildReportData() + { + // There is a several ways to populate document with data: + string doc = MyDir + "Reporting engine template - If greedy.docx"; + + AsposeData obj = new AsposeData { List = new List { "abc" } }; + + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportWithObject.1.docx", obj); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportWithObject.2.docx", obj, new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportWithObject.3.docx", SaveFormat.Docx, obj); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportWithObject.4.docx", SaveFormat.Docx, obj, new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + } + + public class AsposeData + { + public List List { get; set; } + } + //ExEnd:BuildReportData + + [Test] + public void BuildReportDataStream() + { + //ExStart:BuildReportDataStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object) + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data using documents from the stream. + // There is a several ways to populate document with data using documents from the stream: + AsposeData obj = new AsposeData { List = new List { "abc" } }; + + using (FileStream streamIn = new FileStream(MyDir + "Reporting engine template - If greedy.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.BuildReportDataStream.1.docx", FileMode.Create, FileAccess.ReadWrite)) + ReportBuilder.BuildReport(streamIn, streamOut, SaveFormat.Docx, obj); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.BuildReportDataStream.2.docx", FileMode.Create, FileAccess.ReadWrite)) + ReportBuilder.BuildReport(streamIn, streamOut, SaveFormat.Docx, obj, new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + } + //ExEnd:BuildReportDataStream + } + + //ExStart:BuildReportDataSource + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(String, String, Object, String) + //ExFor:ReportBuilder.BuildReport(String, String, Object[], String[]) + //ExFor:ReportBuilder.BuildReport(String, String, Object, String, ReportBuilderOptions) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, String) + //ExFor:ReportBuilder.BuildReport(String, String, SaveFormat, Object, String, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data sources. + [Test] //ExSkip + public void BuildReportDataSource() + { + // There is a several ways to populate document with data sources: + string doc = MyDir + "Report building.docx"; + + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportDataSource.1.docx", sender, "s"); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportDataSource.2.docx", new object[] { sender }, new[] { "s" }); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportDataSource.3.docx", sender, "s", new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportDataSource.4.docx", SaveFormat.Docx, sender, "s"); + ReportBuilder.BuildReport(doc, ArtifactsDir + "LowCode.BuildReportDataSource.5.docx", SaveFormat.Docx, sender, "s", new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + } + + public class MessageTestClass + { + public string Name { get; set; } + public string Message { get; set; } + + public MessageTestClass(string name, string message) + { + Name = name; + Message = message; + } + } + //ExEnd:BuildReportDataSource + + [Test] + public void BuildReportDataSourceStream() + { + //ExStart:BuildReportDataSourceStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object[], String[]) + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, String) + //ExFor:ReportBuilder.BuildReport(Stream, Stream, SaveFormat, Object, String, ReportBuilderOptions) + //ExSummary:Shows how to populate document with data sources using documents from the stream. + // There is a several ways to populate document with data sources using documents from the stream: + MessageTestClass sender = new MessageTestClass("LINQ Reporting Engine", "Hello World"); + + using (FileStream streamIn = new FileStream(MyDir + "Report building.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.BuildReportDataSourceStream.1.docx", FileMode.Create, FileAccess.ReadWrite)) + ReportBuilder.BuildReport(streamIn, streamOut, SaveFormat.Docx, new object[] { sender }, new[] { "s" }); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.BuildReportDataSourceStream.2.docx", FileMode.Create, FileAccess.ReadWrite)) + ReportBuilder.BuildReport(streamIn, streamOut, SaveFormat.Docx, sender, "s"); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.BuildReportDataSourceStream.3.docx", FileMode.Create, FileAccess.ReadWrite)) + ReportBuilder.BuildReport(streamIn, streamOut, SaveFormat.Docx, sender, "s", new ReportBuilderOptions() { Options = ReportBuildOptions.AllowMissingMembers }); + } + //ExEnd:BuildReportDataSourceStream + } + + [Test] + public void RemoveBlankPages() + { + //ExStart:RemoveBlankPages + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.RemoveBlankPages(String, String) + //ExFor:Splitter.RemoveBlankPages(String, String, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document. + // There is a several ways to remove empty pages from the document: + string doc = MyDir + "Blank pages.docx"; + + Splitter.RemoveBlankPages(doc, ArtifactsDir + "LowCode.RemoveBlankPages.1.docx"); + Splitter.RemoveBlankPages(doc, ArtifactsDir + "LowCode.RemoveBlankPages.2.docx", SaveFormat.Docx); + //ExEnd:RemoveBlankPages + } + + [Test] + public void RemoveBlankPagesStream() + { + //ExStart:RemoveBlankPagesStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.RemoveBlankPages(Stream, Stream, SaveFormat) + //ExSummary:Shows how to remove empty pages from the document from the stream. + using (FileStream streamIn = new FileStream(MyDir + "Blank pages.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.RemoveBlankPagesStream.docx", FileMode.Create, FileAccess.ReadWrite)) + Splitter.RemoveBlankPages(streamIn, streamOut, SaveFormat.Docx); + } + //ExEnd:RemoveBlankPagesStream + } + + [Test] + public void ExtractPages() + { + //ExStart:ExtractPages + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.ExtractPages(String, String, int, int) + //ExFor:Splitter.ExtractPages(String, String, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document. + // There is a several ways to extract pages from the document: + string doc = MyDir + "Big document.docx"; + + Splitter.ExtractPages(doc, ArtifactsDir + "LowCode.ExtractPages.1.docx", 0, 2); + Splitter.ExtractPages(doc, ArtifactsDir + "LowCode.ExtractPages.2.docx", SaveFormat.Docx, 0, 2); + //ExEnd:ExtractPages + } + + [Test] + public void ExtractPagesStream() + { + //ExStart:ExtractPagesStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.ExtractPages(Stream, Stream, SaveFormat, int, int) + //ExSummary:Shows how to extract pages from the document from the stream. + using (FileStream streamIn = new FileStream(MyDir + "Big document.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.ExtractPagesStream.docx", FileMode.Create, FileAccess.ReadWrite)) + Splitter.ExtractPages(streamIn, streamOut, SaveFormat.Docx, 0, 2); + } + //ExEnd:ExtractPagesStream + } + + [Test] + public void SplitDocument() + { + //ExStart:SplitDocument + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.Split(String, String, SplitOptions) + //ExFor:Splitter.Split(String, String, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document by pages. + string doc = MyDir + "Big document.docx"; + + Splitter.Split(doc, ArtifactsDir + "LowCode.SplitDocument.1.docx", new SplitOptions() { SplitCriteria = SplitCriteria.Page }); + Splitter.Split(doc, ArtifactsDir + "LowCode.SplitDocument.2.docx", SaveFormat.Docx, new SplitOptions() { SplitCriteria = SplitCriteria.Page }); + //ExEnd:SplitDocument + } + + [Test] + public void SplitDocumentStream() + { + //ExStart:SplitDocumentStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Splitter.Split(Stream, SaveFormat, SplitOptions) + //ExSummary:Shows how to split document from the stream by pages. + using (FileStream streamIn = new FileStream(MyDir + "Big document.docx", FileMode.Open, FileAccess.Read)) + { + Stream[] stream = Splitter.Split(streamIn, SaveFormat.Docx, new SplitOptions() { SplitCriteria = SplitCriteria.Page }); + } + //ExEnd:SplitDocumentStream + } + + [Test] + public void WatermarkText() + { + //ExStart:WatermarkText + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetText(String, String, String) + //ExFor:Watermarker.SetText(String, String, SaveFormat, String) + //ExFor:Watermarker.SetText(String, String, String, TextWatermarkOptions) + //ExFor:Watermarker.SetText(String, String, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document. + string doc = MyDir + "Big document.docx"; + string watermarkText = "This is a watermark"; + + Watermarker.SetText(doc, ArtifactsDir + "LowCode.WatermarkText.1.docx", watermarkText); + Watermarker.SetText(doc, ArtifactsDir + "LowCode.WatermarkText.2.docx", SaveFormat.Docx, watermarkText); + Watermarker.SetText(doc, ArtifactsDir + "LowCode.WatermarkText.3.docx", watermarkText, new TextWatermarkOptions() { Color = Color.Red }); + Watermarker.SetText(doc, ArtifactsDir + "LowCode.WatermarkText.4.docx", SaveFormat.Docx, watermarkText, new TextWatermarkOptions() { Color = Color.Red }); + //ExEnd:WatermarkText + } + + [Test] + public void WatermarkTextStream() + { + //ExStart:WatermarkTextStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetText(Stream, Stream, SaveFormat, String) + //ExFor:Watermarker.SetText(Stream, Stream, SaveFormat, String, TextWatermarkOptions) + //ExSummary:Shows how to insert watermark text to the document from the stream. + string watermarkText = "This is a watermark"; + + using (FileStream streamIn = new FileStream(MyDir + "Document.docx", FileMode.Open, FileAccess.Read)) + { + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.WatermarkTextStream.1.docx", FileMode.Create, FileAccess.ReadWrite)) + Watermarker.SetText(streamIn, streamOut, SaveFormat.Docx, watermarkText); + + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.WatermarkTextStream.2.docx", FileMode.Create, FileAccess.ReadWrite)) + Watermarker.SetText(streamIn, streamOut, SaveFormat.Docx, watermarkText, new TextWatermarkOptions() { Color = Color.Red }); + } + //ExEnd:WatermarkTextStream + } + + [Test] + public void WatermarkImage() + { + //ExStart:WatermarkImage + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetImage(String, String, String) + //ExFor:Watermarker.SetImage(String, String, SaveFormat, String) + //ExFor:Watermarker.SetImage(String, String, String, ImageWatermarkOptions) + //ExFor:Watermarker.SetImage(String, String, SaveFormat, String, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document. + string doc = MyDir + "Document.docx"; + string watermarkImage = ImageDir + "Logo.jpg"; + + Watermarker.SetImage(doc, ArtifactsDir + "LowCode.SetWatermarkImage.1.docx", watermarkImage); + Watermarker.SetImage(doc, ArtifactsDir + "LowCode.SetWatermarkText.2.docx", SaveFormat.Docx, watermarkImage); + Watermarker.SetImage(doc, ArtifactsDir + "LowCode.SetWatermarkText.3.docx", watermarkImage, new ImageWatermarkOptions() { Scale = 50 }); + Watermarker.SetImage(doc, ArtifactsDir + "LowCode.SetWatermarkText.4.docx", SaveFormat.Docx, watermarkImage, new ImageWatermarkOptions() { Scale = 50 }); + //ExEnd:WatermarkImage + } + + [Test] + public void WatermarkImageStream() + { + //ExStart:WatermarkImageStream + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:Watermarker.SetImage(Stream, Stream, SaveFormat, Image) + //ExFor:Watermarker.SetImage(Stream, Stream, SaveFormat, Image, ImageWatermarkOptions) + //ExSummary:Shows how to insert watermark image to the document from a stream. + using (FileStream streamIn = new FileStream(MyDir + "Document.docx", FileMode.Open, FileAccess.Read)) + { +#if NET461_OR_GREATER || JAVA //ExSkip + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.SetWatermarkText.1.docx", FileMode.Create, FileAccess.ReadWrite)) + Watermarker.SetImage(streamIn, streamOut, SaveFormat.Docx, System.Drawing.Image.FromFile(ImageDir + "Logo.jpg")); +#endif //ExSkip + +#if NET461_OR_GREATER || JAVA //ExSkip + using (FileStream streamOut = new FileStream(ArtifactsDir + "LowCode.SetWatermarkText.2.docx", FileMode.Create, FileAccess.ReadWrite)) + Watermarker.SetImage(streamIn, streamOut, SaveFormat.Docx, System.Drawing.Image.FromFile(ImageDir + "Logo.jpg"), new ImageWatermarkOptions() { Scale = 50 }); +#endif //ExSkip + } + //ExEnd:WatermarkImageStream + } } } diff --git a/Examples/ApiExamples/ApiExamples/ExMailMerge.cs b/Examples/ApiExamples/ApiExamples/ExMailMerge.cs index 913453b4..4f9c7b7c 100644 --- a/Examples/ApiExamples/ApiExamples/ExMailMerge.cs +++ b/Examples/ApiExamples/ApiExamples/ExMailMerge.cs @@ -1891,5 +1891,35 @@ public void MustacheTags() } //ExEnd } + + [Test] + public void RemoveEmptyTables() + { + //ExStart:RemoveEmptyTables + //GistId:695136dbbe4f541a8a0a17b3d3468689 + //ExFor:MailMergeCleanupOptions + //ExSummary:Shows how to remove whole empty table during mail merge. + DataTable tableCustomers = new DataTable("A"); + tableCustomers.Columns.Add("CustomerID"); + tableCustomers.Columns.Add("CustomerName"); + tableCustomers.Rows.Add(new object[] { 1, "John Doe" }); + tableCustomers.Rows.Add(new object[] { 2, "Jane Doe" }); + + DataSet ds = new DataSet(); + ds.Tables.Add(tableCustomers); + + Document doc = new Document(MyDir + "Mail merge tables.docx"); + Assert.AreEqual(2, doc.GetChildNodes(NodeType.Table, true).Count); + + doc.MailMerge.MergeDuplicateRegions = false; + doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyTables | MailMergeCleanupOptions.RemoveUnusedRegions; + doc.MailMerge.ExecuteWithRegions(ds.Tables["A"]); + + doc.Save(ArtifactsDir + "MailMerge.RemoveEmptyTables.docx"); + + doc = new Document(ArtifactsDir + "MailMerge.RemoveEmptyTables.docx"); + Assert.AreEqual(1, doc.GetChildNodes(NodeType.Table, true).Count); + //ExEnd:RemoveEmptyTables + } } } diff --git a/Examples/Data/Blank pages.docx b/Examples/Data/Blank pages.docx new file mode 100644 index 0000000000000000000000000000000000000000..9ca2dd7287708ed4cb7f811472c85d71dcc3f232 GIT binary patch literal 18723 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%0A$(_+P*W==( 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 literal 0 HcmV?d00001 diff --git a/Examples/Data/Mail merge with regions data set.docx b/Examples/Data/Mail merge with regions data set.docx new file mode 100644 index 0000000000000000000000000000000000000000..f56f02bc63e8b8497489d463dc8e09f2a6ebd778 GIT binary patch literal 7560 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

~te9BP)JYeU_G=@=h}MzyNk3iE<lbIPX`OPv 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 S{pxRF0^06~@|pP8zyAZdpzWCe literal 0 HcmV?d00001 diff --git a/Examples/Data/Mail merge.doc b/Examples/Data/Mail merge.doc new file mode 100644 index 0000000000000000000000000000000000000000..853e2bdde265b36f62926bfa4eb70b254dd07ffb GIT binary patch literal 20992 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 literal 0 HcmV?d00001