I am using the 2011 Reporting CTP to try anb write code that will take a XamWebChart instance, stick it in a report, then print it. This is all in SL4 and, ideally, no XAML would be involved. I cannot seem to find any useful documentation or samples regarding the relevant classes (Report, Section).
This was a trivial task with Telerik's libraries, but I have not been able to determine how this can be accomplished using Infragistics' libraries.
Hi,
The way to add have a chart printed with the Reporting tool is to create a report in Visual Studio, select a DataSource, drop a chart control on it, attach it to the datasource, set the chart type, etc.
It seems that what you are trying to do is to print a XamWebChart instance. Am I understanding it correctly?
Thanks,
Andres
Hello, Andres: thanks for the quick reply.
Printing is one of the things I want to do with XamWebChart instances, yes. I will also be trying to export them to a variety of formats, but my first experiments have been with simple printing.
In my case I have no DataSource as such, and cannot find documentation on how to construct one that contains a XamWebChart instance. I have no chart control to drop on anything, as the XamWebChart instances are all created dynamically at runtime.
It seems to me like I ought to be able to write code that looks something like this:
var report = new Report();
report.AddSection(myChart)
report.Print(stream);
But it seems it is not that simple. I cannot find any documentatoin on the AddSection() member, so it is not clear that this is even remotely the correct approach. All of the available documentation seems to be focused on databound solutions.
It seems that you are trying to use the Infragistics.Documents assembly that is included with Reporting CTP. That assembly is not shipped with any other Silverlight product, and it's included with Reporting just for internal use. We'd probably replace it for something else in the future.
Infragistics.Documents it's supported and documented in other platforms like WPF/Windows Forms.
If you want to go the Reporting route, you need to do what I mentioned about creating a report, a data source, adding a chart, etc. In that case we'll be using the xamDataChart internally and Reporting supports a subset of the existing chart types in xamDataChart.
The other option is go the Silverlight Printing route, which implies having the xamDataChart in the Visual Tree.
I understand that this is not what you are trying to do, but I don't see other options right now.
Regards,
The only reason I am currently looking at the Reporting CTP is because I was unable to identify a SL4 solution for printing/exporting charts using Infragistics technology. It seemed there were only two paths:
1) Send it to the server and use the server-side Windows/WPF libraries to do the work
2) Extract it as a bitmap and use Silverlight printing.
Neither of these is very attractive in your case. I seem to recall looking at the Infragistics.Documents classes and conluding that the Silverlight versions could did not support printing/exporting. If I was mistaken, I have no problem with using them and would be happy with a link to a good example.
The Infragistics.Documents library ships with Windows Forms and it's documented here
http://help.infragistics.com/Help/NetAdvantage/WinForms/2011.1/CLR2.0/html/Win_Infragistics_Document_Engine.html
The SL version is a port of that one, so it could be slightly different, and as I said, it could not be included in future versions of NA Reporting.
That said, we are using it for exporting XAML controls to PDF with Reporting, so it's possible to do. You cannot use it for printing tough.
To get an image included in the report you need to do something like this:
bool? result = sfd.ShowDialog();
if (result.Value)
{
BitmapSource bitmap = ...; // This object should hold the chart's bitmap
using (var stream = sfd.OpenFile())
var section = report.AddSection();
var encodedBitmap = new MemoryStream();
// for JPEG encoding
new JpegImageEncoder().Encode(bitmap, new List<EncodingProperty> { new JpegQualityProperty { Quality = 100 } }, encodedBitmap);
var image = System.Drawing.Image.FromStream(encodedBitmap);
section.AddImage(new Image(image));
report.Publish(stream, FileFormat.PDF);
}
To create a bitmap from the chart, you can do something like:
bitmap = new WriteableBitmap(chart, null);
Where chart is the instance of xamWebChart, and it should be somewhere in the Visual Tree. If you don't want to show it, you could try putting it into a ViewBox with Opacity = 0.
As I mentioned, our current thinking is not to ship this library as a product that we support, so it could happen that you don't see it in future versions of the tool.
Yes, I have seen code like this in other examples, but the Silverlight library is sufficiently different that I cannot figure out how to apply this pattern. Specifically, the AddSection() method does not take zero arguments in the SL4 implementation. In the SL4 assemblies, AddSection() is an extension method on the Report class and has the signature: AddSection(this Report, Type, Measure, Measure, int, string)My main problem is that I cannot find any documentation as to what would go in the Type slot. If I could get some documentation on the use of this specific method, I could probably figure the rest of it out.Assuming that this can be made to work in SL4, why can I not use it for printing?
Andres:
I was able to build an IImageEncoder implementation around the Stegman PngEncoder class you referred to and, now that I'm actually digging in the right mine, figure out how to use the Word and Excel document classes to get exports to those file formats. Except for the lack of XPS support, I've got all my target formats covered.
That said, PPT (PowerPoint) would be really nice; does Infragistics have anything for that?
Yes, the PngEncoder and XPS are not working in the bits you have. We are not using PNG to encode our images, and we found some issues with XPS so it will probably not ship in Reporting either.
The .AddImage class receives and Image instance, so you could try finding any other encoding code in the web and use it to convert the WriteableBitmap into an Image. If you google for 'Joe Stegman’s PngEncoder' you'll find some code.
You basically had achieved all what you could with the bits you have.
Oops. You need this routine, too:private static void ExportDocument(XamWebChart analytic, string defaultExt, string defaultFilter, FileFormat fileFormat){ var dialog = new SaveFileDialog { DefaultExt = defaultExt, Filter = defaultFilter }; if (dialog.ShowDialog() != true) return; var document = MakeReportFromAnalytic(analytic, 500, 700); using (var stream = dialog.OpenFile()) { document.Publish(stream, fileFormat); }}
Thank you. With that last bit of information I have been able to achieve at least some success. I now have two routines: one that exports a XamWebChart to an image of some format, and one that attempts to export it as a document of some format.In the case of images, the only formats I could find Infragistics encoders for were JPEG and PNG. In the case of documents, the only formats that I could find support for were PDF and XPS.
In my tests, the JPEG and PDF paths work; PNG and XPS fail. The PNG path fails with a "not implemented" exception inside the IImageEncoder.Encode() method, and the XPS path generates a document, but the XPS Viewer cannot display the resulting page.
My code is as follows:private static Report MakeReportFromAnalytic(XamWebChart analytic, int height, int width){ var report = new Report(); var section = report.AddSection(); var bitmap = new WriteableBitmap(analytic, null); using (var encodedBitmap = new MemoryStream()) { new JpegImageEncoder().Encode(bitmap, new List<EncodingProperty> {new gQualityProperty{Quality = 100}}, encodedBitmap); var nativeImage = System.Drawing.Image.FromStream(encodedBitmap); var infragisticsImage = new Image(nativeImage, false); section.AddImage(infragisticsImage); } return report;}private static void ExportImage(XamWebChart analytic, string defaultExt, string defaultFilter, IImageEncoder encoder, IList<EncodingProperty> encodingProperties){ var dialog = new SaveFileDialog { DefaultExt = defaultExt, Filter = defaultFilter }; if (dialog.ShowDialog() != true) return; using (var stream = dialog.OpenFile()) { var bitmap = new WriteableBitmap(analytic, null); using (var encodedBitmap = new MemoryStream()) { encoder.Encode(bitmap, encodingProperties, encodedBitmap); var byteArray = encodedBitmap.ToArray();
stream.Write(byteArray, 0, byteArray.Length); } }}// These two invocations work...private static void ExportAsPdf(XamWebChart analytic){ ExportDocument(analytic, @"*.pdf", @"Adobe PDF Document (*.pdf)|*.pdf", FileFormat.PDF);}private static void ExportAsJpg(XamWebChart analytic){ ExportImage(analytic, @"*.jpg", @"JPEG Image (*.jpg)|*.jpg", new JpegImageEncoder(), new List<EncodingProperty> { new JpegQualityProperty { Quality = 100 } } );}// These two fail as detailed aboveprivate static void ExportAsXps(XamWebChart analytic){ ExportDocument(analytic, @"*.xps", @"Microsoft XPS Document (*.xps)|*.xps", FileFormat.XPS);}private static void ExportAsPng(XamWebChart analytic){ ExportImage(analytic, @"*.png", @"PNG Image (*.png)|*.png", new PngImageEncoder(), new List<EncodingProperty>());}I see no obvious reason for this, particularly for the "not implemented" exception. Beyond that, is there support (using these mechanisms) for any other document or image types beyond the ones I have listed above?
They are in C:\Program Files (x86)\Infragistics\NetAdvantage 2011.2\Reporting\Bin\InfragisticsSL4.Documents.Reports.v11.2.dll
I apologize for not being clear ;), I thought you were already using it.