OOXML : keep images displayed after moving the header content to to the body - openxml-sdk

I am using open XML SDK and I want to move the content of content control (containing images) from the header to the body, the problem that images does not show after moving. After copying the content control content I am adding the image parts in this way :
foreach (var headerPart in wordDocument.MainDocumentPart.HeaderParts)
{
SdtBlock sdtToSave = this.FindSdtBlock(contentControlTag, headerPart );
if (sdtToSave != null)
{
foreach (var imagePart in headerPart.ImageParts)
{
ImagePart newPart = mainPart.AddImagePart(imagePart.ContentType);
this.GenerateImagePartContent(newPart, imagePart.GetStream()); }
}
}
private void GenerateImagePartContent(ImagePart imagePart, Stream partStream)
{
imagePart.FeedData(partStream);
partStream.Close();
}
then if I add this lines :
Paragraph paragraph = sdtToSave.SdtContentBlock.GetFirstChild<Paragraph>();
Run run = new Run();
paragraph.Append(run);
run.Append(this.GenerateDrawing(mainPart.GetIdOfPart(newPart)));
private Drawing GenerateDrawing(String relationshipID)
{
Drawing drawing1 = new Drawing();
Inline inline1 = new Inline() { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U };
Extent extent1 = new Extent() { Cx = 152400L, Cy = 152400L };
EffectExtent effectExtent1 = new EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L };
DocProperties docProperties1 = new DocProperties() { Id = (UInt32Value)1U, Name = "Image 1" };
NonVisualGraphicFrameDrawingProperties nonVisualGraphicFrameDrawingProperties1 = new NonVisualGraphicFrameDrawingProperties();
A.GraphicFrameLocks graphicFrameLocks1 = new A.GraphicFrameLocks() { NoChangeAspect = true };
graphicFrameLocks1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
nonVisualGraphicFrameDrawingProperties1.Append(graphicFrameLocks1);
A.Graphic graphic1 = new A.Graphic();
graphic1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
A.GraphicData graphicData1 = new A.GraphicData() { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" };
Pic.Picture picture1 = new Pic.Picture();
picture1.AddNamespaceDeclaration("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture");
Pic.NonVisualPictureProperties nonVisualPictureProperties1 = new Pic.NonVisualPictureProperties();
Pic.NonVisualDrawingProperties nonVisualDrawingProperties1 = new Pic.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = "AddTo_Blink.png" };
Pic.NonVisualPictureDrawingProperties nonVisualPictureDrawingProperties1 = new Pic.NonVisualPictureDrawingProperties();
nonVisualPictureProperties1.Append(nonVisualDrawingProperties1);
nonVisualPictureProperties1.Append(nonVisualPictureDrawingProperties1);
Pic.BlipFill blipFill1 = new Pic.BlipFill();
A.Blip blip1 = new A.Blip() { Embed = relationshipID };
A.BlipExtensionList blipExtensionList1 = new A.BlipExtensionList();
A.BlipExtension blipExtension1 = new A.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" };
A14.UseLocalDpi useLocalDpi1 = new A14.UseLocalDpi() { Val = false };
useLocalDpi1.AddNamespaceDeclaration("a14", "http://schemas.microsoft.com/office/drawing/2010/main");
blipExtension1.Append(useLocalDpi1);
blipExtensionList1.Append(blipExtension1);
blip1.Append(blipExtensionList1);
A.Stretch stretch1 = new A.Stretch();
A.FillRectangle fillRectangle1 = new A.FillRectangle();
stretch1.Append(fillRectangle1);
blipFill1.Append(blip1);
blipFill1.Append(stretch1);
Pic.ShapeProperties shapeProperties1 = new Pic.ShapeProperties();
A.Transform2D transform2D1 = new A.Transform2D();
A.Offset offset1 = new A.Offset() { X = 0L, Y = 0L };
A.Extents extents1 = new A.Extents() { Cx = 152400L, Cy = 152400L };
transform2D1.Append(offset1);
transform2D1.Append(extents1);
A.PresetGeometry presetGeometry1 = new A.PresetGeometry() { Preset = A.ShapeTypeValues.Rectangle };
A.AdjustValueList adjustValueList1 = new A.AdjustValueList();
presetGeometry1.Append(adjustValueList1);
shapeProperties1.Append(transform2D1);
shapeProperties1.Append(presetGeometry1);
picture1.Append(nonVisualPictureProperties1);
picture1.Append(blipFill1);
picture1.Append(shapeProperties1);
graphicData1.Append(picture1);
graphic1.Append(graphicData1);
inline1.Append(extent1);
inline1.Append(effectExtent1);
inline1.Append(docProperties1);
inline1.Append(nonVisualGraphicFrameDrawingProperties1);
inline1.Append(graphic1);
drawing1.Append(inline1);
return drawing1;
}
all images are shown at the end of body.
From the OXML SDK productivity tool I can see that bookmarks are used to insert images inside a paragraph.
To summarize, I want to know how to keep images when moving content controls from header to the body.
Regards.

When you add your image part to the mainPart, it will be given a relId which is unlikely to be the same as the relId it had in the headerPart. So you'll have to adjust the relId in the drawing (Embed = relationshipID) to match.

Related

Print WebView with multiple pages in Xamarin UWP

I am trying to print web page in xamarin forms. I am using DependencyService to print webview, which I have implemented in android successfully.
For Windows UWP,
I referred to this link:
https://forums.xamarin.com/discussion/91163/problem-with-printing-webview-in-uwp-phone
The approach used in this is printing only the first page of the webpage.
Edit :
I created an interface IPrint providing only the html source to the function.
public interface IPrint
{
void PrintAsync(string htmlSource);
}
In PrintAsync function (in Windows UWP project),
async void IPrint.PrintAsync(string htmlSource)
{
ViewToPrint.NavigateToString(htmlSource);
ViewToPrint.LoadCompleted += ViewToPrint_LoadCompleteAsync;
}
When WebView is completely loaded,
private async void ViewToPrint_LoadCompleteAsync(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
if (PrintDoc != null)
{
printDoc.AddPages -= PrintDoc_AddPages;
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
}
this.printDoc = new PrintDocument();
try
{
printDoc.AddPages += PrintDoc_AddPages;
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
bool showprint = await PrintManager.ShowPrintUIAsync();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
PrintDoc = null;
GC.Collect();
}
To add pages in PrintDocument,
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
{
printDoc.AddPage(ViewToPrint);
printDoc.AddPagesComplete();
}
To implement multiple pages printing,
I referred this link : https://stackoverflow.com/a/17222629/6366591
I changed AddPages function to the following, but it doesn't seem to work for me.
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
{
rectangleList = GetWebPages(ViewToPrint, new Windows.Foundation.Size(100d, 150d));
foreach (Windows.UI.Xaml.Shapes.Rectangle rectangle in rectangleList)
{
printDoc.AddPage(rectangle);
}
printDoc.AddPagesComplete();
}
You can find GetWebPages() function here.
List<Windows.UI.Xaml.Shapes.Rectangle> GetWebPages(Windows.UI.Xaml.Controls.WebView webView, Windows.Foundation.Size page)
{
// ask the content its width
var _WidthString = webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollWidth.toString()" }).GetResults();
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// ask the content its height
var _HeightString = webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollHeight.toString()" }).GetResults();
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// how many pages will there be?
var _Scale = page.Width / _ContentWidth;
var _ScaledHeight = (_ContentHeight * _Scale);
var _PageCount = (double)_ScaledHeight / page.Height;
_PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);
// create the pages
var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
for (int i = 0; i < (int)_PageCount; i++)
{
var _TranslateY = -page.Height * i;
var _Page = new Windows.UI.Xaml.Shapes.Rectangle
{
Height = page.Height,
Width = page.Width,
Margin = new Windows.UI.Xaml.Thickness(5),
Tag = new Windows.UI.Xaml.Media.TranslateTransform { Y = _TranslateY },
};
_Page.Loaded += (s, e) =>
{
var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
var _Brush = GetWebViewBrush(webView);
_Brush.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;
_Brush.AlignmentY = Windows.UI.Xaml.Media.AlignmentY.Top;
_Brush.Transform = _Rectangle.Tag as Windows.UI.Xaml.Media.TranslateTransform;
_Rectangle.Fill = _Brush;
};
_Pages.Add(_Page);
}
return _Pages;
}
WebViewBrush GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)
{
// resize width to content
var _OriginalWidth = webView.Width;
var _WidthString = webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollWidth.toString()" }).GetResults();
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// resize height to content
var _OriginalHeight = webView.Height;
var _HeightString = webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollHeight.toString()" }).GetResults();
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// create brush
var _OriginalVisibilty = webView.Visibility;
webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
var _Brush = new WebViewBrush
{
SourceName = webView.Name,
Stretch = Windows.UI.Xaml.Media.Stretch.Uniform
};
_Brush.Redraw();
// reset, return
webView.Width = _OriginalWidth;
webView.Height = _OriginalHeight;
webView.Visibility = _OriginalVisibilty;
return _Brush;
}
#Jerry Nixon's method worked well on my side. Since his code sample was posted on that thread about five years ago. For current UWP APIs, I just done a little changes(e.g, webView.InvokeScriptAsync). I also saw that you call the webView.InvokeScriptAsync method in your code. That's good. But you call the GetResults() method, I did not suggest you call GetResults() method. Because invoking javascript code sometimes will take you a lot of time. You might get the exception A method was called at an unexpected time.
Then, I also noticed that your printing flow is a bit of a mess. Please read Print from your app to learn the standardized printing process.
You could check the official code sample Printing sample for details.
The following was the updated code of your code snippet:
async Task<List<Windows.UI.Xaml.Shapes.Rectangle>> GetWebPages(Windows.UI.Xaml.Controls.WebView webView, Windows.Foundation.Size page)
{
// ask the content its width
var _WidthString = await webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollWidth.toString()" });
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// ask the content its height
var _HeightString = await webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollHeight.toString()" });
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// how many pages will there be?
var _Scale = page.Width / _ContentWidth;
var _ScaledHeight = (_ContentHeight * _Scale);
var _PageCount = (double)_ScaledHeight / page.Height;
_PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);
// create the pages
var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
for (int i = 0; i < (int)_PageCount; i++)
{
var _TranslateY = -page.Height * i;
var _Page = new Windows.UI.Xaml.Shapes.Rectangle
{
Height = page.Height,
Width = page.Width,
Margin = new Windows.UI.Xaml.Thickness(5),
Tag = new Windows.UI.Xaml.Media.TranslateTransform { Y = _TranslateY },
};
_Page.Loaded +=async (s, e) =>
{
var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
var _Brush = await GetWebViewBrush(webView);
_Brush.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;
_Brush.AlignmentY = Windows.UI.Xaml.Media.AlignmentY.Top;
_Brush.Transform = _Rectangle.Tag as Windows.UI.Xaml.Media.TranslateTransform;
_Rectangle.Fill = _Brush;
};
_Pages.Add(_Page);
}
return _Pages;
}
async Task<WebViewBrush> GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)
{
// resize width to content
var _OriginalWidth = webView.Width;
var _WidthString = await webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollWidth.toString()" });
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
webView.Width = _ContentWidth;
// resize height to content
var _OriginalHeight = webView.Height;
var _HeightString = await webView.InvokeScriptAsync("eval",
new[] { "document.body.scrollHeight.toString()" });
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
webView.Height = _ContentHeight;
// create brush
var _OriginalVisibilty = webView.Visibility;
webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
var _Brush = new WebViewBrush
{
SourceName = webView.Name,
Stretch = Windows.UI.Xaml.Media.Stretch.Uniform
};
_Brush.Redraw();
// reset, return
webView.Width = _OriginalWidth;
webView.Height = _OriginalHeight;
webView.Visibility = _OriginalVisibilty;
return _Brush;
}
I used the Printing sample and put my above updated code in it and do some relevant changes, then I could print all web pages successfully.

How to add watermark to aspose pdf and word that contain table

I generate a Aspose.Generate.Pdf file and then add a Aspose.Pdf.Generator.Tableto it by following method. but when I add watermark to this pdf file, it covers by created table:
public static BasketResult<string> ExportDataTableToPdf(DataTable inputDataTable, string CaptionFilename)
{
List<DataColumn> listDataColumns = GetDataColumns(inputDataTable, CaptionFilename);
BasketResult<string> returnResult = new BasketResult<string>();
String rtnPathFile = String.Empty;
int rowCount = inputDataTable.Rows.Count;
if (rowCount <= 1000)
{
try
{
string dataDir = Settings.TempPath;
if (!Directory.Exists(dataDir))
Directory.CreateDirectory(dataDir);
Pdf pdfConv = new Pdf();
pdfConv.IsRightToLeft = true;
Aspose.Pdf.Generator.Section mainSection = pdfConv.Sections.Add();
mainSection.TextInfo.IsRightToLeft = true;
mainSection.IsLandscape = true;
mainSection.TextInfo.Alignment = AlignmentType.Right;
// header definition begin
Aspose.Pdf.Generator.HeaderFooter header = new Aspose.Pdf.Generator.HeaderFooter(mainSection);
mainSection.EvenHeader = header;
mainSection.OddHeader = header;
header.Margin.Top = 50;
Aspose.Pdf.Generator.Table headerTable = new Aspose.Pdf.Generator.Table();
header.Paragraphs.Add(headerTable);
headerTable.DefaultCellBorder = new BorderInfo((int)BorderSide.All, 0.1F);
headerTable.Alignment = AlignmentType.Right;
headerTable.DefaultColumnWidth = "80";
headerTable.FixedHeight = 30;
Aspose.Pdf.Generator.Row headerRow = headerTable.Rows.Add();
headerRow.BackgroundColor = new Aspose.Pdf.Generator.Color("#D3DFEE");
int index = 0;
listDataColumns.Reverse();
foreach (DataColumn column in listDataColumns)
{
string cellText = column.Caption;
headerRow.Cells.Add(cellText);
headerRow.Cells[index].DefaultCellTextInfo.FontName = "Tahoma";
headerRow.Cells[index].DefaultCellTextInfo.IsRightToLeft = true;
headerRow.Cells[index].VerticalAlignment = VerticalAlignmentType.Center;
headerRow.Cells[index++].Alignment = AlignmentType.Center;
}
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Aspose.Words.Tables.Table wordTable = ImportTableFromDataTable(builder, inputDataTable,
CaptionFilename, true);
string columnWidths = "";
for (int j = 0; j < wordTable.FirstRow.Count; j++)
{
columnWidths = columnWidths + "80 ";
}
Aspose.Pdf.Generator.Table table = new Aspose.Pdf.Generator.Table();
mainSection.Paragraphs.Add(table);
table.ColumnWidths = columnWidths;
table.DefaultCellBorder = new BorderInfo((int)BorderSide.All, 0.1F);
table.Alignment = AlignmentType.Right;
//fill table
for (int i = 1; i < wordTable.Rows.Count; i++)
{
Aspose.Pdf.Generator.Row row = table.Rows.Add();
row.BackgroundColor = i % 2 == 0
? new Aspose.Pdf.Generator.Color("#D3DFEE")
: new Aspose.Pdf.Generator.Color("#FFFFFF");
var wordTableRow = wordTable.Rows[i];
//fill columns from end to begin because table is left to right
for (int c = wordTable.FirstRow.Count - 1; c >= 0; c--)
{
var cellValue = wordTableRow.ChildNodes[c];
string cellText = cellValue.GetText();
row.Cells.Add(cellText);
}
//set style to every cell
for (int c = 0; c < wordTable.FirstRow.Count; c++)
{
row.Cells[c].DefaultCellTextInfo.FontName = "Tahoma";
row.Cells[c].DefaultCellTextInfo.IsRightToLeft = true;
row.Cells[c].VerticalAlignment = VerticalAlignmentType.Center;
row.Cells[c].Alignment = AlignmentType.Center;
}
}
pdfConv.SetUnicode();
rtnPathFile = Helper.GetTempFile() + ".pdf";
string fileName = Helper.GetFileNameFromFilePath(rtnPathFile);
pdfConv = AddPdfWatermark(pdfConv);
pdfConv.Save(dataDir + fileName);
returnResult.Result.Add(rtnPathFile);
returnResult.IsSuccess = true;
}
catch (Exception ex)
{
rtnPathFile = String.Empty;
returnResult.IsSuccess = false;
returnResult.Result.Add(rtnPathFile);
returnResult.persianErrorMessages.Add(Messages.Err_InvalidFilePath);
}
}
else
{
returnResult.IsSuccess = false;
returnResult.Result.Add(rtnPathFile);
returnResult.persianErrorMessages.Add(Messages.Err_CreateFile);
}
return returnResult;
}
and AddPdfWatermerk method is :
private static Pdf AddPdfWatermark(Aspose.Pdf.Generator.Pdf pdfConv)
{
try
{
// Create FloatingBox with x as width and y as height
Aspose.Pdf.Generator.FloatingBox background = new Aspose.Pdf.Generator.FloatingBox(); // width, height
Aspose.Pdf.Generator.Image backImage = new Aspose.Pdf.Generator.Image();
string path = HttpContext.Current.Server.MapPath("~/images/PrivateExcelBackGround.png");
byte[] bgBuffer = File.ReadAllBytes(path);
MemoryStream streamBack = new MemoryStream(bgBuffer, false);
backImage.ImageInfo.ImageStream = streamBack;
background.Paragraphs.Add(backImage);
background.ZIndex = 1000;
pdfConv.Watermarks.Add(background);
pdfConv.IsWatermarkOnTop = false;
return pdfConv;
}
catch
{
return pdfConv;
}
}
I tried stamp instead of watermark, but table masks it too.
in aspose.words.document file I have a problem too, in word file with mentioned table,watermark added correctly but when a colored alternate table rows, watermark covered by colorful rows.
You are using an out-dated version of Aspose.PDF API. Kindly upgrade to Aspose.PDF for .NET 18.1, which includes more features and bug fixes. You can add an image stamp by using below code snippet in your environment.
// Open document
Document pdfDocument = new Document(dataDir+ "AddImageStamp.pdf");
// Create image stamp
ImageStamp imageStamp = new ImageStamp(dataDir + "aspose-logo.jpg");
imageStamp.Background = true;
imageStamp.XIndent = 100;
imageStamp.YIndent = 100;
imageStamp.Height = 300;
imageStamp.Width = 300;
imageStamp.Rotate = Rotation.on270;
imageStamp.Opacity = 0.5;
// Add stamp to particular page
pdfDocument.Pages[1].AddStamp(imageStamp);
dataDir = dataDir + "AddImageStamp_out.pdf";
// Save output document
pdfDocument.Save(dataDir);
ImageStamp class provides the properties necessary for creating an image-based stamp, such as height, width, opacity etc. You may visit Adding stamp in a PDF file for further information on this topic. In case you notice any problem with the file generated by using this code, please get back to us with source and generated file so that we may proceed to help you out.
I work with Aspose as Developer Evangelist.

Change colors in devexpress charts

I am drawing a pie chart using Devexpress in my MVC project.
While doing it by default my chart generated with three colors, as below
but my client is not satisfied, with the colors of it and wanted me to change them which match with our application background, so please help me, how to do this.
Thanks in advance.
Here is my code.
settings.Name = "chart";
settings.Width = 600;
settings.Height = 250;
settings.BorderOptions.Visible = false;
Series series1 = new Series("Type", DevExpress.XtraCharts.ViewType.Pie3D);
settings.Series.Add(series1);
series1.ArgumentScaleType = ScaleType.Qualitative;
series1.ArgumentDataMember = "ClassName";
series1.ValueScaleType = ScaleType.Numerical;
series1.ValueDataMembers.AddRange(new string[] { "PercentageValues" });
series1.LegendPointOptions.PointView = PointView.ArgumentAndValues;
series1.LegendPointOptions.ValueNumericOptions.Format = NumericFormat.Percent;
series1.LegendPointOptions.ValueNumericOptions.Precision = 0;
series1.Label.ResolveOverlappingMode = ResolveOverlappingMode.Default;
series1.Label.Visible = false;
Please refer the following code. I have successfully implemented the same for giving custom color for rangebar. I guess it will work for your case also
settings.CustomDrawSeriesPoint = (s, ev) =>
{
BarDrawOptions drawOptions = ev.SeriesDrawOptions as BarDrawOptions;
if (drawOptions == null)
return;
Color colorInTarget = Color.Blue;
double x = ev.SeriesPoint.Values[0];
double y = ev.SeriesPoint.Values[1];
if (x == 0)
{ //Do starting
colorInTarget = Color.FromArgb(159,125, 189);
}
else{
//Red - price Increase
// Green price Decrease
if (y > previousYValue)
{
colorInTarget = Color.Red; ;
}
else
{
colorInTarget = Color.Green;
}
}
previousYValue = y;
drawOptions.Color = colorInTarget;
drawOptions.FillStyle.FillMode = FillMode.Solid;
drawOptions.Border.Color = Color.Transparent;
};
you can set the theme and palette properties of the chart control. follow the links below to devexpress documentation. although the examples refers to winform application they are still avaliable in asp.net mvc controls.
http://documentation.devexpress.com/#WindowsForms/CustomDocument7433
http://documentation.devexpress.com/#WindowsForms/CustomDocument5538
// Define the chart's appearance and palette.
barChart.AppearanceName = "Dark";
barChart.PaletteName = "Opulent";
private List<StudentClass.ChartsPointsSummary> GetStudentSummaryResults()
{
var StudentId = Convert.ToInt32(Request.Params["StudentID"]);
var StudentDetailsP = CtxSM.SMISGet_StudentAttendanceDetailsByStudentId(StudentId, SessionDataManager.SessionData.LoginUserId, SessionDataManager.SessionData.AcademicYearID, SessionDataManager.SessionData.BusinessUnitId, ref outError).ToList();
var Presents = StudentDetailsP.Select(p => new { p.Months, p.Presents});
var CountsP = StudentDetailsP.Count();
List<StudentClass.ChartsPointsSummary> MT = new List<StudentClass.ChartsPointsSummary>();
foreach (var ab in Presents)
{
MT.Add(new StudentClass.ChartsPointsSummary { PresentSummaryX = ab.Months, PresentSummaryY = Convert.ToInt32(ab.Presents) });
}
var StudentDetailsA = CtxSM.SMISGet_StudentAttendanceDetailsByStudentId(StudentId, SessionDataManager.SessionData.LoginUserId, SessionDataManager.SessionData.AcademicYearID, SessionDataManager.SessionData.BusinessUnitId, ref outError).ToList();
var Absents = StudentDetailsP.Select(p => new { p.Months, p.Absents });
var CountsA = StudentDetailsA.Count();
foreach (var ab in Absents)
{
MT.Add(new StudentClass.ChartsPointsSummary { AbsentSummaryX = ab.Months, AbsentSummaryY = Convert.ToInt32(ab.Absents) });
}
var StudentDetailsL = CtxSM.SMISGet_StudentAttendanceDetailsByStudentId(StudentId, SessionDataManager.SessionData.LoginUserId, SessionDataManager.SessionData.AcademicYearID, SessionDataManager.SessionData.BusinessUnitId, ref outError).ToList();
var CountL = StudentDetailsL.Count();
var Leaves = StudentDetailsP.Select(p => new { p.Months, p.Leaves });
foreach (var ab in Leaves)
{
MT.Add(new StudentClass.ChartsPointsSummary { LeaveSummaryX = ab.Months, LeaveSummaryY = Convert.ToInt32(ab.Leaves) });
}
return MT;
}
#Html.DevExpress().Chart(settings =>
{
settings.Name = "SummaryDetailsById";
settings.Width = 1032;
settings.Height = 250;
Series chartSeries = new Series("Presents", DevExpress.XtraCharts.ViewType.Bar);
chartSeries.ArgumentDataMember = "PresentSummaryX";
chartSeries.ValueDataMembers[0] = "PresentSummaryY";
settings.Series.Add(chartSeries);
Series chartSeries2 = new Series("Absents", DevExpress.XtraCharts.ViewType.Bar);
chartSeries2.ArgumentDataMember = "AbsentSummaryX";
chartSeries2.ValueDataMembers[0] = "AbsentSummaryY";
settings.Series.Add(chartSeries2);
Series chartSeries3 = new Series("Leaves", DevExpress.XtraCharts.ViewType.Bar);
chartSeries3.ArgumentDataMember = "LeaveSummaryX";
chartSeries3.ValueDataMembers[0] = "LeaveSummaryY";
settings.Series.Add(chartSeries3);
settings.CrosshairEnabled = DefaultBoolean.Default;
settings.BackColor = System.Drawing.Color.Transparent;
settings.BorderOptions.Visibility = DefaultBoolean.True;
settings.Titles.Add(new ChartTitle()
{
Text = "Student Attendance Summary"
});
XYDiagram diagram = ((XYDiagram)settings.Diagram);
diagram.AxisX.Label.Angle = -30;
diagram.AxisY.Interlaced = true;
}).Bind(Model).GetHtml()

How do I get an in-memory chart (or image) into an in-memory OpenXML document?

I'm having a nightmare of a time trying to add a Chart to a MemoryStream in-memory.
I'm creating a Word document on the fly using OpenXML and I have a chart that is also being dynamically generated from data in the database.
I get the template from the database as a byte array, passing that into a method that also takes a business object that holds a bunch of data to populate bookmarks held within that template.
Here's the method:
public Stream Parse(byte[] array, AudiometryReport AudReport)
{
using (MemoryStream Stream = new MemoryStream())
{
Stream.Write(array, 0, (int)array.Length);
Stream.Position = 0;
using (document = WordprocessingDocument.Open(Stream, true))
{
XDocument doc = document.MainDocumentPart.GetXDocument();
List<XElement> bookmarks = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkStart")
.ToList();
PropertyInfo[] reportInfo = AudReport.GetType().GetProperties();
foreach (XElement bm in bookmarks)
{
try
{
if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);
var element = AddImageToDocument(document.MainDocumentPart, partId);
//var element = InsertImageXElement(partId);
//bm.ReplaceWith(new XElement(w + "r", element));
}
else
{
string val = reportInfo.Single(x => x.Name == bm.LastAttribute.Value).GetValue(AudReport, null).ToString();
bm.ReplaceWith(new XElement(w + "r",
new XElement(w + "t", val)));
}
}
catch
{ }
}
document.MainDocumentPart.PutXDocument();
//foreach (BookmarkStart bm in (IEnumerable<BookmarkStart>)document.MainDocumentPart.Document.Descendants<BookmarkStart>())
//{
// if (bm.Name == "AudiometryChart")
// {
// // Insert the chart object here.
// //AddImage(document);
// }
// populateStaffDetails(AudReport.Report.Employee, bm);
// populateAudiometryDetails(AudReport, bm);
//}
}
MemoryStream s = new MemoryStream();
Stream.WriteTo(s);
s.Position = 0;
return s;
}
}
The InsertImage image takes the MainDocumentPart and attaches a new ImagePart from the image I stream from the database. I pass the ID of that part back to the calling method.
private string InsertImage(MainDocumentPart docPart)
{
//DrawingsPart dp = docPart.AddNewPart<DrawingsPart>();
//ImagePart part = dp.AddImagePart(ImagePartType.Png, docPart.GetIdOfPart(dp));
ImagePart part = docPart.AddImagePart(ImagePartType.Png);
Chart cht = new ChartBuilder().DoChart(Data, new string[] { "Left", "Right", "Normal" });
using (MemoryStream ms = new MemoryStream())
{
cht.SaveImage(ms, ChartImageFormat.Png);
ms.Position = 0;
part.FeedData(ms);
}
//int count = dp.ImageParts.Count<ImagePart>();
int count = docPart.ImageParts.Count<ImagePart>();
return docPart.GetIdOfPart(part);
}
The last part is some serious nastiness that is allegdly required to add one image to one word document, but what the hell - here it is anyway:
private Run AddImageToDocument(MainDocumentPart docPart, string ImageRelId)
{
string ImageFileName = "Audiometry Chart Example";
string GraphicDataUri = "http://schemas.openxmlformats.org/drawingml/2006/picture";
long imageLength = 990000L;
long imageHeight = 792000L;
var run = new Run(
new Drawing(
new wp.Inline(
new wp.Extent() { Cx = imageLength, Cy = imageHeight },
new wp.EffectExtent()
{
LeftEdge = 19050L,
TopEdge = 0L,
RightEdge = 9525L,
BottomEdge = 0L
},
new wp.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Inline Text Wrapping Picture",
Description = ImageFileName
},
new wp.NonVisualGraphicFrameDrawingProperties(
new a.GraphicFrameLocks() { NoChangeAspect = true }),
new a.Graphic(
new a.GraphicData(
new pic.Picture(
new pic.NonVisualPictureProperties(
new pic.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = ImageFileName },
new pic.NonVisualPictureDrawingProperties()),
new pic.BlipFill(
new a.Blip() { Embed = ImageRelId },
new a.Stretch(
new a.FillRectangle())),
new pic.ShapeProperties(
new a.Transform2D(
new a.Offset() { X = 0L, Y = 0L },
new a.Extents() { Cx = imageLength, Cy = imageHeight }),
new a.PresetGeometry(
new a.AdjustValueList()) { Preset = a.ShapeTypeValues.Rectangle }))
) { Uri = GraphicDataUri }))
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U
}
));
return run;
}
So I've solved issues where the memory stream was causing problems by closing prematurely and probably a dozen other unnecessary amateur garden path problems but that image will just not show up in my document. Frustrating. Suggestions or divine inspiration very welcome right now.
(this question has been heavily edited so some answers may not relate to the wording of this question).
I've just tested your AddImageToDocument function in a small test
scenario using the following code:
string partId = ...
Run element = AddImageToDocument(newdoc.MainDocumentPart, partId);
Paragraph p = new Paragraph() { RsidParagraphAddition = "00EA6221", RsidRunAdditionDefault = "008D25CC" };
p.AppendChild(element);
newdoc.MainDocumentPart.Document.Body.Append(p);
// Save the word document here...
Everything works as expected and the image shows up in the word document.
Then I've come to the conclusion that the problem in your code must be the replacement of the bookmarkStart tag and the conversion
of the Run (containing the image) to an XElement.
So, I've modified your code in the following way (using XElement.Parse to convert
an OpenXmlElement to a XElement):
foreach (XElement bm in bookmarks)
{
try
{
if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);
Run element = AddImageToDocument(document.MainDocumentPart, partId);
bm.ReplaceWith(XElement.Parse(element.OuterXml)); // Use XElement.Parse to convert an OpenXmlElement to an XElement.
}
else
{
... }
}
}
catch
{
}
}
The image now shows up in the word document.
Then I've analyzed the word document using the
OpenXml SDK productivity tool and found that the bookmarkEnd tags still exist in the document.
To remove those tags use the following code:
List<XElement> bookmarksEnd = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkEnd")
.ToList();
foreach (XElement x in bookmarksEnd)
{
x.Remove();
}
Edit 3: :o)
Ok, I found the problem.
If you initialize the document's MemoryStream with the doc content, the buffer will be fixed in size and not editable. Just changed the init to write the doc content after creation and all seemd to work fine.
//using (MemoryStream stream = new MemoryStream (docxFile))
using (MemoryStream stream = new MemoryStream ())
{
stream.Write (docxFile, 0, docxFile.Length);
stream.Position = 0;
using (WordprocessingDocument docx = WordprocessingDocument.Open (stream, true))
{
[....]
Cheers

Open XML SDK - image not showing in excel

I'm able to successfully create a spreadsheet, and I appear to have added the image via code, the problem is that when I open the spreadsheet, there is no image. Here is my code:
public static void CreateSpreadsheetWorkbook(string filepath)
{
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet" };
sheets.Append(sheet);
string sImagePath = #"C:\temp\install_button.png";
DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
ImagePart imagePart = drawingsPart.AddImagePart(ImagePartType.Png, worksheetPart.GetIdOfPart(drawingsPart));
using (FileStream stream = new FileStream(sImagePath, FileMode.Open))
{
imagePart.FeedData(stream);
}
workbookpart.Workbook.Save();
spreadsheetDocument.Close();
}
Thanks
Stu
Normally when I can't figure out why something doesn't work when dealing with the Open XML SDK I use the Open XML SDK 2.0 Productivity Tool to figure out what the code should be. I will normally create a blank worksheet in Excel, add a picture and then save the document. Then I will open that document in the Productivity tool and click the Reflect code button to see how to recreate that document. I did that to see how to answer your question and got the following code to create a worksheet part:
// Adds child parts and generates content of the specified part.
public void CreateWorksheetPart(WorksheetPart part)
{
DrawingsPart drawingsPart1 = part.AddNewPart<DrawingsPart>("rId2");
GenerateDrawingsPart1Content(drawingsPart1);
ImagePart imagePart1 = drawingsPart1.AddNewPart<ImagePart>("image/png", "rId1");
GenerateImagePart1Content(imagePart1);
SpreadsheetPrinterSettingsPart spreadsheetPrinterSettingsPart1 = part.AddNewPart<SpreadsheetPrinterSettingsPart>("rId1");
GenerateSpreadsheetPrinterSettingsPart1Content(spreadsheetPrinterSettingsPart1);
GeneratePartContent(part);
}
// Generates content of drawingsPart1.
private void GenerateDrawingsPart1Content(DrawingsPart drawingsPart1)
{
Xdr.WorksheetDrawing worksheetDrawing1 = new Xdr.WorksheetDrawing();
worksheetDrawing1.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
worksheetDrawing1.AddNamespaceDeclaration("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
Xdr.TwoCellAnchor twoCellAnchor1 = new Xdr.TwoCellAnchor(){ EditAs = Xdr.EditAsValues.OneCell };
Xdr.FromMarker fromMarker1 = new Xdr.FromMarker();
Xdr.ColumnId columnId1 = new Xdr.ColumnId();
columnId1.Text = "0";
Xdr.ColumnOffset columnOffset1 = new Xdr.ColumnOffset();
columnOffset1.Text = "0";
Xdr.RowId rowId1 = new Xdr.RowId();
rowId1.Text = "0";
Xdr.RowOffset rowOffset1 = new Xdr.RowOffset();
rowOffset1.Text = "0";
fromMarker1.Append(columnId1);
fromMarker1.Append(columnOffset1);
fromMarker1.Append(rowId1);
fromMarker1.Append(rowOffset1);
Xdr.ToMarker toMarker1 = new Xdr.ToMarker();
Xdr.ColumnId columnId2 = new Xdr.ColumnId();
columnId2.Text = "0";
Xdr.ColumnOffset columnOffset2 = new Xdr.ColumnOffset();
columnOffset2.Text = "171429";
Xdr.RowId rowId2 = new Xdr.RowId();
rowId2.Text = "0";
Xdr.RowOffset rowOffset2 = new Xdr.RowOffset();
rowOffset2.Text = "171429";
toMarker1.Append(columnId2);
toMarker1.Append(columnOffset2);
toMarker1.Append(rowId2);
toMarker1.Append(rowOffset2);
Xdr.Picture picture1 = new Xdr.Picture();
Xdr.NonVisualPictureProperties nonVisualPictureProperties1 = new Xdr.NonVisualPictureProperties();
Xdr.NonVisualDrawingProperties nonVisualDrawingProperties1 = new Xdr.NonVisualDrawingProperties(){ Id = (UInt32Value)2U, Name = "Picture 1", Description = "eprs_reports_arrow.png" };
Xdr.NonVisualPictureDrawingProperties nonVisualPictureDrawingProperties1 = new Xdr.NonVisualPictureDrawingProperties();
A.PictureLocks pictureLocks1 = new A.PictureLocks(){ NoChangeAspect = true };
nonVisualPictureDrawingProperties1.Append(pictureLocks1);
nonVisualPictureProperties1.Append(nonVisualDrawingProperties1);
nonVisualPictureProperties1.Append(nonVisualPictureDrawingProperties1);
Xdr.BlipFill blipFill1 = new Xdr.BlipFill();
A.Blip blip1 = new A.Blip(){ Embed = "rId1", CompressionState = A.BlipCompressionValues.Print };
blip1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
A.Stretch stretch1 = new A.Stretch();
A.FillRectangle fillRectangle1 = new A.FillRectangle();
stretch1.Append(fillRectangle1);
blipFill1.Append(blip1);
blipFill1.Append(stretch1);
Xdr.ShapeProperties shapeProperties1 = new Xdr.ShapeProperties();
A.Transform2D transform2D1 = new A.Transform2D();
A.Offset offset1 = new A.Offset(){ X = 0L, Y = 0L };
A.Extents extents1 = new A.Extents(){ Cx = 171429L, Cy = 171429L };
transform2D1.Append(offset1);
transform2D1.Append(extents1);
A.PresetGeometry presetGeometry1 = new A.PresetGeometry(){ Preset = A.ShapeTypeValues.Rectangle };
A.AdjustValueList adjustValueList1 = new A.AdjustValueList();
presetGeometry1.Append(adjustValueList1);
shapeProperties1.Append(transform2D1);
shapeProperties1.Append(presetGeometry1);
picture1.Append(nonVisualPictureProperties1);
picture1.Append(blipFill1);
picture1.Append(shapeProperties1);
Xdr.ClientData clientData1 = new Xdr.ClientData();
twoCellAnchor1.Append(fromMarker1);
twoCellAnchor1.Append(toMarker1);
twoCellAnchor1.Append(picture1);
twoCellAnchor1.Append(clientData1);
worksheetDrawing1.Append(twoCellAnchor1);
drawingsPart1.WorksheetDrawing = worksheetDrawing1;
}
// Generates content of imagePart1.
private void GenerateImagePart1Content(ImagePart imagePart1)
{
System.IO.Stream data = GetBinaryDataStream(imagePart1Data);
imagePart1.FeedData(data);
data.Close();
}
// Generates content of spreadsheetPrinterSettingsPart1.
private void GenerateSpreadsheetPrinterSettingsPart1Content(SpreadsheetPrinterSettingsPart spreadsheetPrinterSettingsPart1)
{
System.IO.Stream data = GetBinaryDataStream(spreadsheetPrinterSettingsPart1Data);
spreadsheetPrinterSettingsPart1.FeedData(data);
data.Close();
}
// Generates content of part.
private void GeneratePartContent(WorksheetPart part)
{
Worksheet worksheet1 = new Worksheet();
worksheet1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
SheetDimension sheetDimension1 = new SheetDimension(){ Reference = "A1" };
SheetViews sheetViews1 = new SheetViews();
SheetView sheetView1 = new SheetView(){ TabSelected = true, WorkbookViewId = (UInt32Value)0U };
sheetViews1.Append(sheetView1);
SheetFormatProperties sheetFormatProperties1 = new SheetFormatProperties(){ DefaultRowHeight = 15D };
SheetData sheetData1 = new SheetData();
PageMargins pageMargins1 = new PageMargins(){ Left = 0.7D, Right = 0.7D, Top = 0.75D, Bottom = 0.75D, Header = 0.3D, Footer = 0.3D };
PageSetup pageSetup1 = new PageSetup(){ Orientation = OrientationValues.Portrait, Id = "rId1" };
Drawing drawing1 = new Drawing(){ Id = "rId2" };
worksheet1.Append(sheetDimension1);
worksheet1.Append(sheetViews1);
worksheet1.Append(sheetFormatProperties1);
worksheet1.Append(sheetData1);
worksheet1.Append(pageMargins1);
worksheet1.Append(pageSetup1);
worksheet1.Append(drawing1);
part.Worksheet = worksheet1;
}
#region Binary Data
private string imagePart1Data ="lots of binary data here";
private System.IO.Stream GetBinaryDataStream(string base64String)
{
return new System.IO.MemoryStream(System.Convert.FromBase64String(base64String));
}
#endregion
I recommend you do the same with your image and play around with the generated code in order to get it to work since as you can see just adding one picture to a new slide is a lot of code.

Resources