Thursday, August 16, 2007

Revised Dynamic RDLC Generation

I've revised some of the RLDC generation code. The basic idea is to build rather generic RLDC file off a DataSet. You can then bind both the DataSet and the RDLC to a ReportViewer control and get your report. I generate the RDLC by transforming the DataSet XML schema into a RDLC file via and XSLT transform.

Let me say that you can greatly improve the XSLT. In a custom solution where I've implemented this, I have a Page Header with the report title, column widths that expand to fit the whole page and a Footer. But that solution is highly customized and not fit as a generic report generator. Just keep in mind that you may adjust the XSLT to fit your needs.

First the code for C# helper class...


using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace x
{
/// <summary>
/// Summary description for RdlcEngine
/// </summary>
public class RdlcEngine
{
public RdlcEngine()
{
//
// TODO: Add constructor logic here
//
}

#region bind control
public static void BindControl(Microsoft.Reporting.WebForms.ReportViewer rv, DataSet data, string name)
{
string virtualRldc = HRWebsite.RdlcEngine.BuildRDLC(data, name);
BindControl(rv, data, name, virtualRldc);
}

public static void BindControl(Microsoft.Reporting.WebForms.ReportViewer rv, DataSet data, string name, string virtualRldc)
{
rv.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;

Microsoft.Reporting.WebForms.ReportDataSource rds = new Microsoft.Reporting.WebForms.ReportDataSource();
rds.Name = name + "_Table";
rds.Value = data.Tables[0];

Microsoft.Reporting.WebForms.LocalReport r = rv.LocalReport;
r.ReportPath = virtualRldc;
r.DataSources.Add(rds);
}
#endregion

#region RDLC
/// <summary>
/// constructs a simple report RDLC file based on a DataSet
/// </summary>
/// <param name="data"></param>
/// <param name="name"></param>
/// <returns></returns>
public static string BuildRDLC(DataSet data, string name)
{
// establish some file names
string virtualXslt = "xslt/rdlc.xsl";
string virtualRdlc = "rdlc/" + name + ".rdlc";
string virtualSchema = "rdlc/" + name + ".schema";

// set the NAME on the DataSet
// this may or may not be necessary, but the RDLC and DataSet
// will both have the same name if this is done.
data.DataSetName = name;

// write the DataSet Schema to a file
// we should be passing a DataSet with only one DataTable
// the rdlc.xsl does not account for multiple DataTables
string physicalSchema = HttpContext.Current.Server.MapPath(virtualSchema);
data.WriteXmlSchema(physicalSchema);

// load the DataSet schema in a DOM
XmlDocument xmlDomSchema = new XmlDocument();
xmlDomSchema.Load(physicalSchema);

// append the NAME to the schema DOM
// this is so we can pick it up in the rdlc.xsl
// and use it
xmlDomSchema.DocumentElement.SetAttribute("Name", name + "_Table");

// transform the Schema Xml with rdlc.xsl
string physicalXslt = HttpContext.Current.Server.MapPath(virtualXslt);
string xml = HRWebsite.General.TransformXml(xmlDomSchema.OuterXml, physicalXslt);

// save off the resultng RDLC file
string physicalRdlc = HttpContext.Current.Server.MapPath(virtualRdlc);
XmlDocument xmlDomRdlc = new XmlDocument();
xmlDomRdlc.LoadXml(xml);
xmlDomRdlc.Save(physicalRdlc);

// return the virtual path of the RDLC file
// this is needed by the asp:ReportViewer
return virtualRdlc;
}
#endregion

#region Render
public static byte[] RenderReport(DataSet data, string name, string type)
{
Microsoft.Reporting.WebForms.ReportDataSource rds = new Microsoft.Reporting.WebForms.ReportDataSource();
rds.Name = name + "_Table";
rds.Value = data.Tables[0];

string virtualRdlc = BuildRDLC(data, name);
Microsoft.Reporting.WebForms.LocalReport lr = new Microsoft.Reporting.WebForms.LocalReport();
lr.ReportPath = HttpContext.Current.Server.MapPath(virtualRdlc);
lr.DataSources.Add(rds);

return RenderReport(lr, name, type);
}

public static byte[] RenderReport(Microsoft.Reporting.WebForms.LocalReport lr, string name, string type)
{
string extension = string.Empty;
string mimeType = string.Empty;
switch (type)
{
case "PDF":
extension = "pdf";
mimeType = "application/pdf";
break;
case "Excel":
extension = "xls";
mimeType = "application/vnd.excel";
break;
case "Image":
extension = "emf";
mimeType = "application/image";
break;
default:
throw new Exception("Unrecognized type: " + type + ". Type must be PDF, Excel or Image.");
}

//The DeviceInfo settings should be changed based on the reportType
//http://msdn2.microsoft.com/en-us/library/ms155397.aspx
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<DeviceInfo>");
sb.Append("<OutputFormat>");
sb.Append(type);
sb.Append("</OutputFormat>");
sb.Append("<PageWidth>11in</PageWidth>");
sb.Append("<PageHeight>8.5in</PageHeight>");
sb.Append("<MarginTop>1in</MarginTop>");
sb.Append("<MarginLeft>1in</MarginLeft>");
sb.Append("<MarginRight>1in</MarginRight>");
sb.Append("<MarginBottom>1in</MarginBottom>");
sb.Append("</DeviceInfo>");
string deviceInfo = sb.ToString();

string encoding;
Microsoft.Reporting.WebForms.Warning[] warnings;
string[] streams;
byte[] result;

//Render the report
result = lr.Render(
type,
deviceInfo,
out mimeType,
out encoding,
out extension,
out streams,
out warnings);

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = mimeType;
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + name + "." + extension);
HttpContext.Current.Response.BinaryWrite(result);
HttpContext.Current.Response.End();

return result;
}
#endregion
}
}


Next, the XSLT....


<?xml version="1.0"?>
<!-- Stylesheet for creating ReportViewer RDLC documents -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"
>

<xsl:variable name="mvarName" select="/xs:schema/@Name"/>
<xsl:variable name="mvarFontSize">8pt</xsl:variable>
<xsl:variable name="mvarFontWeight">500</xsl:variable>
<xsl:variable name="mvarFontWeightBold">700</xsl:variable>


<xsl:template match="/">
<xsl:apply-templates select="/xs:schema/xs:element/xs:complexType/xs:choice/xs:element/xs:complexType/xs:sequence">
</xsl:apply-templates>
</xsl:template>

<xsl:template match="xs:sequence">
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition">
<BottomMargin>1in</BottomMargin>
<RightMargin>1in</RightMargin>
<LeftMargin>1in</LeftMargin>
<TopMargin>1in</TopMargin>
<InteractiveHeight>11in</InteractiveHeight>
<InteractiveWidth>8.5in</InteractiveWidth>
<Width>6.5in</Width>
<Language>en-US</Language>
<rd:DrawGrid>true</rd:DrawGrid>
<rd:SnapToGrid>true</rd:SnapToGrid>
<rd:ReportID>7358b654-3ca3-44a0-8677-efe0a55c7c45</rd:ReportID>

<xsl:call-template name="BuildDataSource">
</xsl:call-template>

<xsl:call-template name="BuildDataSet">
</xsl:call-template>

<Body>
<Height>0.50in</Height>
<ReportItems>
<Table Name="table1">
<DataSetName><xsl:value-of select="$mvarName" /></DataSetName>
<Top>0.5in</Top>
<Height>0.50in</Height>
<Header>
<TableRows>
<TableRow>
<Height>0.25in</Height>
<TableCells>

<xsl:apply-templates select="xs:element" mode="HeaderTableCell">
</xsl:apply-templates>

</TableCells>
</TableRow>
</TableRows>
</Header>
<Details>
<TableRows>
<TableRow>
<Height>0.25in</Height>
<TableCells>

<xsl:apply-templates select="xs:element" mode="DetailTableCell">
</xsl:apply-templates>

</TableCells>
</TableRow>
</TableRows>
</Details>
<TableColumns>

<xsl:apply-templates select="xs:element" mode="TableColumn">
</xsl:apply-templates>

</TableColumns>
</Table>
</ReportItems>
</Body>
</Report>
</xsl:template>

<xsl:template name="BuildDataSource">
<DataSources>
<DataSource Name="DummyDataSource">
<ConnectionProperties>
<ConnectString/>
<DataProvider>SQL</DataProvider>
</ConnectionProperties>
<rd:DataSourceID>84635ff8-d177-4a25-9aa5-5a921652c79c</rd:DataSourceID>
</DataSource>
</DataSources>
</xsl:template>

<xsl:template name="BuildDataSet">
<DataSets>
<DataSet Name="{$mvarName}">
<Query>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
<CommandText/>
<DataSourceName>DummyDataSource</DataSourceName>
</Query>
<Fields>

<xsl:apply-templates select="xs:element" mode="Field">
</xsl:apply-templates>

</Fields>
</DataSet>
</DataSets>
</xsl:template>

<xsl:template match="xs:element" mode="Field">
<xsl:variable name="varFieldName">
<xsl:value-of select="@name" />
</xsl:variable>

<xsl:variable name="varDataType">
<xsl:choose>
<xsl:when test="@type='xs:int'">System.Int32</xsl:when>
<xsl:when test="@type='xs:string'">System.String</xsl:when>
<xsl:when test="@type='xs:dateTime'">System.DateTime</xsl:when>
<xsl:when test="@type='xs:boolean'">System.Boolean</xsl:when>
</xsl:choose>
</xsl:variable>

<Field Name="{$varFieldName}">
<rd:TypeName><xsl:value-of select="$varDataType"/></rd:TypeName>
<DataField><xsl:value-of select="$varFieldName"/></DataField>
</Field>
</xsl:template>

<xsl:template match="xs:element" mode="HeaderTableCell">
<xsl:variable name="varFieldName">
<xsl:value-of select="@name" />
</xsl:variable>

<TableCell>
<ReportItems>
<Textbox Name="textbox{position()}">
<rd:DefaultName>textbox<xsl:value-of select="position()"/>
</rd:DefaultName>
<Value><xsl:value-of select="$varFieldName"/></Value>
<CanGrow>true</CanGrow>
<ZIndex>7</ZIndex>
<Style>
<TextAlign>Center</TextAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingBottom>2pt</PaddingBottom>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<FontSize><xsl:value-of select="$mvarFontSize"/></FontSize>
<FontWeight><xsl:value-of select="$mvarFontWeightBold"/></FontWeight>
<BackgroundColor>#000000</BackgroundColor>
<Color>#ffffff</Color>
<BorderColor>
<Default>#ffffff</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</Textbox>
</ReportItems>
</TableCell>
</xsl:template>

<xsl:template match="xs:element" mode="DetailTableCell">
<xsl:variable name="varFieldName">
<xsl:value-of select="@name" />
</xsl:variable>

<TableCell>
<ReportItems>
<Textbox Name="{$varFieldName}">
<rd:DefaultName><xsl:value-of select="$varFieldName"/></rd:DefaultName>
<Value>=Fields!<xsl:value-of select="$varFieldName"/>.Value</Value>
<CanGrow>true</CanGrow>
<ZIndex>7</ZIndex>
<Style>
<TextAlign>Left</TextAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingBottom>2pt</PaddingBottom>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<FontSize><xsl:value-of select="$mvarFontSize"/></FontSize>
<FontWeight><xsl:value-of select="$mvarFontWeight"/></FontWeight>
<BackgroundColor>#e0e0e0</BackgroundColor>
<Color>#000000</Color>
<BorderColor>
<Default>#ffffff</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</Textbox>
</ReportItems>
</TableCell>
</xsl:template>

<xsl:template match="xs:element" mode="TableColumn">
<TableColumn>
<Width>0.75in</Width>
</TableColumn>
</xsl:template>

<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="from"/>
<xsl:param name="to"/>
<xsl:choose>
<xsl:when test="contains($text, $from)">
<xsl:variable name="before" select="substring-before($text, $from)"/>
<xsl:variable name="after" select="substring-after($text, $from)"/>
<xsl:variable name="prefix" select="concat($before, $to)"/>
<xsl:value-of select="$before"/>
<xsl:value-of select="$to"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="$after"/>
<xsl:with-param name="from" select="$from"/>
<xsl:with-param name="to" select="$to"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

45 comments:

Olivier said...

I have test your code and i like your solution.
I have a problem.
My report doesn't appear.
I can export into excel but i don't see the table in reportviewer.
Do you have any suggestion

Oliver

Dan Shipe said...

If you can export to Excel, it would seem the code is working for. That is, it is generating the rdlc (and you should be able to verify that you are generating a rdlc to a physical file on your web server). If you've got the physical file of the rdlc, you can open in Visual Studio 2005. That should let you what is working and what is not.

Alternatively, try checking the Report Viewer control that you have placed on your page. I have the following settings to the ASPX control...

<rsweb:ReportViewer ID="ReportViewer1" runat="server"
asyncrendering="False"
sizetoreportcontent="True"
showtoolbar="True"
>
</rsweb:ReportViewer>

Olivier said...

Very nice.
That work fine
You are the best of the dynamic rdlc engine

mary said...

I Got the code to work. Looks really good. I would like a report header, report footer in my report. Would I make the change to the Xslt file? Also want to have friendly column name. How would I go about doing that? Thanks for the code!

Dan Shipe said...

Mary,
The easiest way to do this is now that you have the basic RDLC file, simply edit it inside VS 2005. Visual Studic 2005 gives a GUI interface for creating headers, footers and the like. Make your changes, and save the RDLC back to the physical file. Now open the physical file in an editor like notepad and see how VS 2005 changed the XML of the RDLC to accomodate your changes. Then all you need to do is make those same changes in your XSLT.

Andy said...

I like your solution for dynamic report. I need to further research to do more complex operations like dynamic grouping etc.. Thank you for sharing it.
I have problem compiling it in VS 2005. Here is the exception I got.

Could not find a part of the path 'C:\Samples\WebSite1\xslt\rdlc.xsl'.

I can reference an external path outside the web application(i.e 'c\test\rdlc.xsl') and it worked without having problem.

Not quite sure what the problem is. Any comment on it?
Thanks again for the source code.

Andy

Dan Shipe said...

Andy,
Just make sure the path (virtual or physical) points to the actually XLST file, either on your hard drive or on your web server. You can try using a breakpoint to check the path, and when you've reached the break, double check the path.

Gonza said...
This comment has been removed by the author.
Gonza said...

That's a good solution for dynamic report. But, how can i add the interactive sort action?
cuase I am trying to add it in the rdlc.xsl file,

UserSort>
SortExpression>
xsl:value-of select="$varFieldName"/>
/SortExpression>
/UserSort>

------------
The report work fine,but when I click on the sort icon (in each column)
It seems the report will reload but when the page is refreshed there is no changes.

Do you know what could be the problem?
Thanks
Gonzalo

rumi said...

I have a problem. HRWebsite.General.TransformXml code is not included here. Can anyone help!

Frank said...

Any chance you could provide a complete sample? This is my first run at something like this and am pretty lost with how to assign the dataset to the xslt and then bind everything. Thanks in advance for any help.

Frank

Frank said...

What's with the

string xml = HRWebsite.General.TransformXml(xmlDomSchema.OuterXml, physicalXslt);

I tried removeing the 'HRWebsite' and the 'General' but still get errors

Frank said...

OK, so I am a newbie and found this article and have wrestled with how to implement the class for over 24 hrs now, and my opinion is that it asolutley sucks that you only provide bare bones code... nothing about how to call the class with sample parameters or a working demo. I managed to run
RdlcEngine.BuildRDLC(ds, "DailyStatement"); and it did create an rdlc but when I try to run RdlcEngine.BindControl it runs without error but nothing appears. Then I tried running RenderReport and I get an exception that says
{"The report definition is not valid.
Details: The element 'Report' in namespace 'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition' has invalid child element 'html'
in namespace 'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition'.

List of possible elements expected:
'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:Description
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:Author
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:AutoRefresh
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:DataSources
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:DataSets
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:Body
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:ReportParameters
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:Code
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:Width
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:PageHeader
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:PageFooter
http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:PageHeight http://schemas...."}

I feel like I wasted a ton of time and no one seems to respond to this anymore. Overall, crappy example spread out over two postings (without any clarification of that)

Rafferty Uy said...

This is great. It saved me days of work. Do you have ideas on how to make the column width dynamic also? I have some tables which has short column names and some with long ones which will display in 3-5 lines with the current width setting. :-s

To the others who don't know what TransformXml(...) is, look at Dan's earlier post of this engine:
http://csharpshooter.blogspot.com/2007/08/generate-rdlc-dynamically-for-vs-2005.html

ano said...

iam new to this rdlc report,will u please give me the code that implement it,i meant any application that used rdlc reports

Kitty said...

.I use reportviewr to show a report(.rdlc) and it can run normally .But I want to change the column name base on the actual data,I have no idea.please give me suggestion.

Majid said...

I dont want the physical files to be created for data set schema and rdlc files on web server. So i changed the functions and make a compact version given below.

public void BuildBind(Microsoft.Reporting.WebForms.ReportViewer reportViewer, DataSet rdlc,string name)
{
MemoryStream memRDLC=null;
try
{
// establish some file names
string schema, virtualXslt = "rdlc.xsl";
// load the DataSet schema in a DOM
System.Xml.XmlDocument xmlDomSchema = new System.Xml.XmlDocument();
schema = rdlc.GetXmlSchema();
// Convert the encoding of unicode representation
schema = schema.Replace("encoding=\"utf-16\"", "standalone=\"yes\"");
xmlDomSchema.LoadXml(schema);
xmlDomSchema.DocumentElement.SetAttribute("Name", name + "_Table");
// transform the Schema Xml with rdlc.xsl
string physicalXslt = Server.MapPath(virtualXslt);
string xml = TransformXml(xmlDomSchema.OuterXml, physicalXslt);
xml = xml.Replace("encoding=\"utf-16\"", "standalone=\"yes\"");
// Convert the generated rdl into memory stream
memRDLC = new System.IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml));
// Bind the rdl memory stream and data set to reportviewer
reportViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;
Microsoft.Reporting.WebForms.ReportDataSource rds = new Microsoft.Reporting.WebForms.ReportDataSource(name + "_Table", rdlc.Tables[0]);
Microsoft.Reporting.WebForms.LocalReport r = reportViewer.LocalReport;
r.LoadReportDefinition(memRDLC);
r.DataSources.Add(rds);
r.Refresh();
}
catch (Exception ex)
{ throw ex; }
finally
{memRDLC.Close();}
}
public static string TransformXml(string xml, string xslFile)
{
string result = string.Empty;

using (System.IO.MemoryStream memory = new System.IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml)))
{
System.Xml.Xsl.XslCompiledTransform transform = new System.Xml.Xsl.XslCompiledTransform();
transform.Load(xslFile);

System.Xml.XPath.XPathDocument xpathDoc = new System.Xml.XPath.XPathDocument(memory);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter sw = new System.IO.StringWriter(sb);
transform.Transform(xpathDoc, null, sw);
result = sb.ToString();

}
return result;
}

mandy said...

Hi,
my report will have 3-4 tables and i need to modify the xsl to accommodate these changes.

I am not able to do that. Can you please help me out how to do that.

I need the solution urgently.

Thanks and Regards,
Mandakini Agrawal

susan said...

Hi, I need to change the give names to Excel sheets in the exported files from RDLC. I have multiple sheets. Please advice me how to do that.

Regards
Suganthi

sonali said...

An error occurred during local report processing.
The definition of the report 'Main Report' is invalid.
The report definition is not valid. Details: The element 'Style' in namespace 'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition' has invalid child element 'Backgroundcolor' in namespace 'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition'. List of possible elements expected: 'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BorderColor http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BorderStyle http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BorderWidth http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BackgroundColor http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BackgroundGradientType http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BackgroundGradientEndColor http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:BackgroundImage http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:FontStyle http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:FontFamily http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:FontSize http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition:FontWeight http://schemas.microsoft.com/sqlserver/reportin....

How to solve this??

Jay said...

you state you have revised the xslt to add header and footer as well as resize the tablecolumn...
this is exactly what I need to do and was wondering if you could point me in the right direction...

I have no experience with xslt files...

imthisgurl said...

I am using this approach to generate rdlc for my reportviewer at runtime. It works fine except for its zoom and export functions. I get a 'ClientToolbarctl00_ContentHolder_reportviewer_ctl01' javascript error when click on those links. Please assist.

Marina said...

First of all, great post and great code. I am not an expert with Microsoft Reports at all and needed a dynamic solution very fast. I've copied and tried your code... however (there is always a however), I remain stuck on one last part when trying to view my dynamic report in the report viewer: "a datasource instance has not been supplied for the datasource xxx_Table". Any help you can give would be very much appreciated! Here is my code:
DataTable dt = List();
ReportManager reportManager = new ReportManager();

reportViewer.ProcessingMode = ProcessingMode.Local;

LocalReport localReport = reportViewer.LocalReport;

// Create a report data source localReport.DataSources.Clear();
ReportDataSource dataSource = new ReportDataSource("DummyDataSource", dt);
localReport.DataSources.Add(dataSource);

localReport.ReportEmbeddedResource = reportManager.BuildTemplate(dt);

// Refresh the report
reportViewer.RefreshReport();

Gonzalo said...

Very nice.
Do you have ideas on how use in Win APP ?
Thanks

ayesha said...

excellent ...can u plz guide me i want to use it in window application. ...and how dynamic datasets or datatables can be bind wid report viewer....thnx

balusblog said...

hi
great post.i tried the sample.
how can i create XSLT for a matrix?

regards
balu

Dead Mike said...

I have successfully extended this to extract info from and use a DataTable, however, I am trying to extend it to handle image columns from the database.

I added a few new functions following your standard, to set imagetype and it's attributes, but I get an error "There was an error generating the XML document."

Here is what I added. See anything? I key of the column name, which is "image":

private Rdl.ReportItemsType CreateTableCellReportItems(string fieldName)
{
Rdl.ReportItemsType reportItems = new Rdl.ReportItemsType();
if ("image" == fieldName)
reportItems.Items = new object[] { CreateTableCellImage(fieldName) };
else
reportItems.Items = new object[] { CreateTableCellTextbox(fieldName) };
return reportItems;
}

// new funcs
private Rdl.ImageType CreateTableCellImage(string fieldName)
{
Rdl.ImageType imageBox = new Rdl.ImageType();
imageBox.Name = fieldName;
imageBox.Items = new object[]
{
"=Fields!" + fieldName + ".Value",
CreateTableCellImageStyle(),
CreateTableCellImageTypeSource(),
CreateTableCellImageMimeType(),
};
imageBox.ItemsElementName = new Rdl.ItemsChoiceType15[]
{
Rdl.ItemsChoiceType15.Value,
Rdl.ItemsChoiceType15.Style,
Rdl.ItemsChoiceType15.Source,
Rdl.ItemsChoiceType15.MIMEType,
};
return imageBox;
}

private Rdl.StyleType CreateTableCellImageStyle()
{
Rdl.StyleType style = new Rdl.StyleType();
style.Items = new object[]
{
"=iif(RowNumber(Nothing) mod 2, \"AliceBlue\", \"White\")",
"Solid",
};
style.ItemsElementName = new Rdl.ItemsChoiceType5[]
{
Rdl.ItemsChoiceType5.BackgroundColor,
Rdl.ItemsChoiceType5.BorderStyle,
};
return style;
}

private Rdl.ImageTypeSource CreateTableCellImageTypeSource()
{
return Rdl.ImageTypeSource.Database;
}

private string CreateTableCellImageMimeType()
{
return "image/bmp";
}

Dead Mike said...

haha, just as i posted, i resolved it. it works, it was the 'style' tag, which I just removed but didn't resolve yet...

thanx for the original work, I see it is used all over the net, you set the standard everyone is now copying your code. ;)

barby_sw said...

i need to do that
by RDL and XSL
and <rsweb:ReportViewer

but my problem is
i have one dataset containig 3 DataTables

the first datatable will be the first row and starting from column 2
and the second datatables will be the second rowstarting from column 2

and the third datatable will be Header and details starting from column 1


so what can i do?
plz help me and this is the first time to me to deal with XSLT and RDL so help me and how can i start.
many thanks.

barby_sw said...

i need to do that
by RDL and XSL
and <rsweb:ReportViewer

but my problem is
i have one dataset containig 3 DataTables

the first datatable will be the first row and starting from column 2
and the second datatables will be the second rowstarting from column 2

and the third datatable will be Header and details starting from column 1


so what can i do?
plz help me and this is the first time to me to deal with XSLT and RDL so help me and how can i start.
many thanks.

Myron said...

You might take a look at www.rptgen.com

Thanks

Myron said...

You might take a look at www.rptgen.com

Thanks

Jari said...

Hello,
i have tried the forst version of this excellent code. It works fine.

Is it possible to get example project how to use this updated version of the class?

How to create master/detail report using this class?

Thaks!

-jari

Jari said...
This comment has been removed by the author.
Myron said...

The free download from the web site, www.rptgen.com has some sample code of how to use the control. There are not currently no samples of a master/detail report. I will develop some and send them to you

Thanks
Myron Joy

Alex said...

@balusblog

Have you figured out the XSLT for matrix format?

Uday Kumar Reddy said...

Hi am unable to get the result can any one send me sample code file?? please help me out..

Rajeshwaran said...

God is there representation of Dan Smith

Sandhya Murkute said...

I want to know where
could you provide me with general.transformxml definitaion

Sandhya Murkute said...

i want to know what is the defination of HRWebsite.General.TransformXml(xmlDomSchema.OuterXml, physicalXslt) defination

alvin almodal said...

Hello! thank you for this wonderful helper class! any ideas on how i could make the column headers repeat on every new page?

Jeff Dressing said...

Thank you for this post! It worked great, however now it is 2014 and I am trying to use a newer version of Visual Studio designer. It prompts to upgrade the RDLC file the code creates.

Is there a newer version of the XSL file available?

Thank you!
Jeff

Jeff Dressing said...

If I try opening it in Visual Studio 2012 and save the RDLC file, the ReportViewer says the RDLC file is corrupted.

Really strange... Visual Studio 2012 designer opens/edits it fine... but the ReportViewer cannot handle it from VS 2012.

MP Nill said...

I need to generate runtime add text in rdlc report If anyone known it then send me mail on " old6number@gmail.com " plz someone help me help me

Md Razu Ahmed said...



Reverse Innovation
Globalization and outsourcing have led to "reverse innovation."
The world is no longer a one-way outsourcing street moving from West to East.
While the West still exports many high-end products and services to developing
nations (and still sources cheap labor), innovations in emerging markets are
now flowing back to the West as well. This is happening with Brazil, China, and
India across such diverse fields as biofuels, IT, and medicine. New approaches to
making cheap artificial hips in India, for example, are finding their way back to
the U.S. and Europe. Plus, reverse innovation often means frugal innovation, which
is welcome in a world where access to capital, land, labor, and natural resources
has become a pressing strategic business issue tied to sustainability.




generation
server
forex
money
game