or
private
void
PrintReportNeedDataSource(
object
sender, EventArgs e)
{
if
(((IList) ReportParameters[
"GUID"
].Value).Count == 0)
return
;
var guidAsString = ((IList) ReportParameters[
"GUID"
].Value)[0].ToString();
var reportData =
new
ReportServices().FetchReportDataForGUID(guidAsString);
var report = (Telerik.Reporting.Processing.Report) sender;
report.DataSource = reportData;
var availableWidth = report.PageSettings.PaperSize.Width - (report.PageSettings.Margins.Left + report.PageSettings.Margins.Right);
// panel1 (used when only one type of chart is to be displayed)
var panel1 =
new
Panel
{
Location =
new
PointU(
new
Unit(0, UnitType.Cm),
new
Unit(0, UnitType.Cm)),
Size =
new
SizeU(
availableWidth,
new
Unit(35, UnitType.Mm)),
Dock = DockStyle.Top,
KeepTogether =
true
};
// panel2 (used with panel1 when multiple chart types are to be displayed on top of each other
var panel2 =
new
Panel
{
Location =
new
PointU(
new
Unit(0, UnitType.Cm),
new
Unit(0, UnitType.Cm)),
Size =
new
SizeU(
availableWidth,
new
Unit(40, UnitType.Mm)),
Dock = DockStyle.Top,
KeepTogether =
true
};
panel2.Style.Padding.Top =
new
Unit(10, UnitType.Mm);
// Report title
titleField.Value = reportData.ReportTitle;
#region Create charts
switch
(reportData.ReportType)
{
case
Enumerators.PrintReportType.Consumption:
case
Enumerators.PrintReportType.ComparedConsumption:
case
Enumerators.PrintReportType.Prognose:
foreach
(var chartData
in
reportData.Charts)
{
var chartImage = Image.FromStream(
new
MemoryStream(chartData.Data));
var perCentageToChange = panel1.Width / Unit.FromPixels(chartImage.Width, UnitType.Mm);
var pBox =
new
PictureBox
{
Name =
string
.Format(
"CD{0}"
, reportData.Charts.IndexOf(chartData)),
Location =
new
PointU(
new
Unit(0),
new
Unit(0)),
Sizing = ImageSizeMode.ScaleProportional,
Width = availableWidth,
Height = Unit.FromPixels(chartImage.Height, UnitType.Mm) * perCentageToChange,
Value = chartImage,
Dock = DockStyle.Top
};
panel1.Items.AddRange(
new
ReportItemBase[] {pBox});
}
if
(panel1.Items.Count != 0)
detail.Items.AddRange(
new
ReportItemBase[] { panel1 });
break
;
case
Enumerators.PrintReportType.StackedConsumption:
foreach
(var chartData
in
reportData.MiscPictures)
{
// Calculate how wide a single image can be to fill the width of the page
var totalWidthInPx = reportData.MiscPictures.Sum(pic => pic.Width);
var totalWidthInMm = Unit.FromPixels(totalWidthInPx, UnitType.Mm);
var perCentageToChange = availableWidth.Value / totalWidthInMm.Value;
var widthPerImage = totalWidthInPx / reportData.MiscPictures.Count * perCentageToChange;
var chartImage = Image.FromStream(
new
MemoryStream(chartData.Data));
var pBox =
new
PictureBox
{
Name =
string
.Format(
"GCD{0}"
, reportData.MiscPictures.IndexOf(chartData)),
Width = Unit.FromPixels(widthPerImage, UnitType.Mm),
Value = chartImage,
Sizing = ImageSizeMode.ScaleProportional,
Dock = DockStyle.Left,
Location =
new
PointU(
new
Unit(0),
new
Unit(0))
};
pBox.Style.Padding.Bottom = Unit.Mm(5);
panel1.Items.AddRange(
new
ReportItemBase[] { pBox });
}
if
(panel1.Items.Count != 0)
detail.Items.AddRange(
new
ReportItemBase[] { panel1 });
foreach
(var chartData
in
reportData.Charts)
{
var chartImage = Image.FromStream(
new
MemoryStream(chartData.Data));
var chartWidth = Unit.FromPixels(chartImage.Width, UnitType.Mm);
var perCentageChange = availableWidth / chartWidth;
var pBox =
new
PictureBox
{
Name =
string
.Format(
"CD{0}"
, reportData.Charts.IndexOf(chartData)),
Location =
new
PointU(
new
Unit(0),
new
Unit(0)),
Sizing = ImageSizeMode.ScaleProportional,
Width = availableWidth,
Height = Unit.FromPixels(chartImage.Height, UnitType.Mm)*perCentageChange,
Value = chartImage,
Dock = DockStyle.Top
};
panel2.Items.AddRange(
new
ReportItemBase[] { pBox });
}
if
(panel2.Items.Count != 0)
detail.Items.AddRange(
new
ReportItemBase[] { panel2 });
// Stacked chart doesn't have any table data and can return
return
;
default
:
throw
new
ArgumentOutOfRangeException();
}
#endregion
#region Create padding between charts and table
var paddingPanel =
new
Panel
{
Size =
new
SizeU(
availableWidth,
Unit.Cm(1.5)),
Dock = DockStyle.Top
};
detail.Items.AddRange(
new
ReportItemBase[] { paddingPanel });
#endregion
#region Create table data
using
(var parser =
new
GenericParserAdapter(
new
StringReader(reportData.TableDataCsv)))
{
parser.FirstRowHasHeader =
true
;
reportData.DataTable = parser.GetDataTable();
}
// Creating and configuring the ObjectDataSource component:
var objectDataSource =
new
ObjectDataSource
{
Name =
"TableDataSource"
,
DataSource = reportData.DataTable
};
//var tableDataAsCollectionOfDynamics = reportData.DataTable.ToDynamic();
report.DataSource = objectDataSource;
var dataTable =
new
Table
{
Name =
"DataTable"
,
DataSource = objectDataSource,
Location =
new
PointU(
new
Unit(0),
new
Unit(0)),
Size =
new
SizeU(
availableWidth,
new
Unit(40, UnitType.Mm)),
Dock = DockStyle.Fill,
ColumnHeadersPrintOnEveryPage =
true
};
detail.Items.Add(dataTable);
//create two HtmlTextBox items (one for header and one for data) which would be added to the items collection of the table
TextBox textBoxHeader;
TextBox textBoxContent;
var i = 0;
dataTable.ColumnHeadersPrintOnEveryPage =
true
;
dataTable.Body.Rows.Add(
new
TableBodyRow(
new
Unit(0.1, UnitType.Cm)));
// Create Padding- and DetailGroup (RowGrops)
var paddingGroup =
new
TableGroup { Name =
"PaddingGroup"
};
var detailGroup =
new
TableGroup { Name =
"DetailGroup"
};
detailGroup.Groupings.Add(
new
Grouping(
""
));
#region If the reporttype is prognosis, create grouping by PrognoseType
switch
(reportData.ReportType)
{
case
Enumerators.PrintReportType.Consumption:
case
Enumerators.PrintReportType.StackedConsumption:
case
Enumerators.PrintReportType.ComparedConsumption:
dataTable.RowGroups.Add(detailGroup);
break
;
case
Enumerators.PrintReportType.Prognose:
// Add an additional row to the body (padding)
dataTable.Body.Rows.Add(
new
TableBodyRow(
new
Unit(0.1, UnitType.Cm)));
var prognoseTypeHeader =
new
TextBox
{
Value =
"Prognos"
,
Name =
"PrognosHeader"
,
Size =
new
SizeU(
Unit.Cm(0.1),
Unit.Cm(0.1)),
Multiline =
true
,
TextWrap =
true
,
CanGrow =
false
,
CanShrink =
true
};
dataTable.Corner.SetCellContent(0, 0, prognoseTypeHeader);
var prognoseTypeContent =
new
TextBox
{
Name =
"PrognosContent"
,
Multiline =
false
,
CanGrow =
false
,
CanShrink =
true
,
Size =
new
SizeU(
Unit.Cm(1.1),
Unit.Mm(0))
};
prognoseTypeContent.Style.Padding.Top = Unit.Mm(0);
prognoseTypeContent.Style.Padding.Bottom = Unit.Mm(0);
prognoseTypeContent.Style.Color = Color.DimGray;
prognoseTypeContent.Style.VerticalAlign = VerticalAlign.Middle;
prognoseTypeContent.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
prognoseTypeContent.Style.BorderColor.Default = Color.AliceBlue;
prognoseTypeContent.Style.BorderStyle.Default = BorderType.Solid;
prognoseTypeContent.Style.BorderWidth.Default = Unit.Point(0.5);
prognoseTypeContent.Value =
"=Fields.Prognostyp"
;
// Add the header and content to the table
dataTable.Items.AddRange(
new
ReportItemBase[]
{
prognoseTypeHeader,
prognoseTypeContent
});
// Create RowGroup to group by PrognoseType
var rowGroupingGroup =
new
TableGroup { Name =
"PrognoseGrouping"
};
rowGroupingGroup.Groupings.Add(
new
Grouping(
"=Fields.Prognostyp"
));
rowGroupingGroup.Sortings.Add(
new
Sorting(
"=Fields.Prognostyp"
, SortDirection.Asc));
rowGroupingGroup.ChildGroups.Add(detailGroup);
rowGroupingGroup.ChildGroups.Add(paddingGroup);
rowGroupingGroup.ReportItem = prognoseTypeContent;
dataTable.RowGroups.Add(rowGroupingGroup);
break
;
default
:
throw
new
ArgumentOutOfRangeException();
}
#endregion
foreach
(DataColumn dc
in
reportData.DataTable.Columns)
{
// The prognosetype column is already handled
if
(reportData.ReportType == Enumerators.PrintReportType.Prognose && dc.ColumnName ==
"Prognostyp"
)
continue
;
// Encode the column name to make spacing work with the table
dc.ColumnName = TelerikUtil.EncodeIdentifier(dc.ColumnName);
// Create the colgroup
var tableColumnGroup =
new
TableGroup { Name =
string
.Format(
"ColGroup{0}"
, reportData.DataTable.Columns.IndexOf(dc)) };
dataTable.ColumnGroups.Add(tableColumnGroup);
dataTable.Body.Columns.Add(
new
TableBodyColumn(i == 0
? Unit.Cm(0.5)
: Unit.Cm(1)));
#region Create header for the column
textBoxHeader =
new
TextBox
{
Name =
string
.Format(
"Header{0}"
, dc.ColumnName),
Value = TelerikUtil.DecodeIdentifier(dc.ColumnName),
Size =
new
SizeU(
Unit.Cm(0.1),
Unit.Cm(0.1)),
Multiline =
true
,
TextWrap =
true
,
CanGrow =
false
,
CanShrink =
true
};
textBoxHeader.Style.VerticalAlign = VerticalAlign.Middle;
textBoxHeader.Style.TextAlign = HorizontalAlign.Center;
textBoxHeader.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
textBoxHeader.Style.Font.Bold =
true
;
textBoxHeader.Style.BackgroundColor = Color.FromName(
"ControlLight"
);
textBoxHeader.Style.BorderColor.Default = Color.AliceBlue;
textBoxHeader.Style.BorderStyle.Default = BorderType.Solid;
textBoxHeader.Style.BorderWidth.Default = Unit.Point(0.5);
// Bind the headern as ReportItem for the colGroup
tableColumnGroup.ReportItem = textBoxHeader;
#endregion
#region Create content for the column
textBoxContent =
new
TextBox
{
Name =
string
.Format(
"Content{0}"
, dc.ColumnName),
Multiline =
false
,
CanGrow =
false
,
CanShrink =
true
,
Size =
new
SizeU(
Unit.Cm(1.1),
Unit.Mm(0))
};
textBoxContent.Style.Padding.Top = Unit.Mm(0);
textBoxContent.Style.Padding.Bottom = Unit.Mm(0);
textBoxContent.Style.Color = Color.DimGray;
textBoxContent.Style.VerticalAlign = VerticalAlign.Middle;
textBoxContent.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
textBoxContent.Style.BorderColor.Default = Color.AliceBlue;
textBoxContent.Style.BorderStyle.Default = BorderType.Solid;
textBoxContent.Style.BorderWidth.Default = Unit.Point(0.5);
#region Content value binding & formatting
if
(textBoxHeader.Value.Contains(
"Procent"
) || textBoxHeader.Value.Contains(
"%"
))
{
var ltZeroFormat =
new
FormattingRule();
var gtZeroFormat =
new
FormattingRule();
ltZeroFormat.Filters.AddRange(
new
[]
{
new
Filter(
string
.Format(
"=CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))"
,dc.ColumnName),
FilterOperator.LessThan,
"0"
)
});
ltZeroFormat.Style.Color = Color.Green;
gtZeroFormat.Filters.AddRange(
new
[]
{
new
Filter(
string
.Format(
"=CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))"
,dc.ColumnName),
FilterOperator.GreaterThan,
"0"
)
});
gtZeroFormat.Style.Color = Color.Red;
textBoxContent.ConditionalFormatting.AddRange(
new
[]
{
ltZeroFormat,
gtZeroFormat
});
textBoxContent.Value =
string
.Format(
"=(CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))/100)"
, dc.ColumnName);
textBoxContent.Format =
"{0:P2}"
;
}
else
if
(
!textBoxHeader.Value.Contains(
"Tidpunkt"
) &&
!textBoxHeader.Value.Contains(
"Kvartal"
))
textBoxContent.Value =
string
.Format(
"=CDbl(Fields.{0})"
, dc.ColumnName);
else
textBoxContent.Value =
string
.Format(
"=Fields.{0}"
, dc.ColumnName);
#endregion
#endregion
if
(reportData.ReportType == Enumerators.PrintReportType.Prognose)
{
var dummyPadding =
new
TextBox
{
Name =
string
.Format(
"Padding{0}"
, dc.ColumnName),
Size =
new
SizeU(
Unit.Cm(1),
Unit.Mm(3))
};
dataTable.Body.SetCellContent(0, i, dummyPadding);
dataTable.Body.SetCellContent(1, i++, textBoxContent);
// Add the dummy padding item to the table
dataTable.Items.Add(dummyPadding);
}
else
{
dataTable.Body.SetCellContent(0, i++, textBoxContent);
}
// Add header and content to the table
dataTable.Items.AddRange(
new
ReportItemBase[]
{
textBoxHeader,
textBoxContent
});
}
#endregion
}
"\"Prognostyp\",\"Kvartal\",\"Utfall\",\"Prognos\",\"Kvartalssumma\",\"Referens\",\"Procent\"\r\n\"Budget\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\r\n\"Budget\",\"Q2\",\"85 173\",\"31 463\",\"116 636\",\"117 133\",\"-0,42 %\"\r\n\"Budget\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\r\n\"Budget\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\"\r\n\"P1\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\r\n\"P1\",\"Q2\",\"85 173\",\"28 317\",\"113 490\",\"105 420\",\"7,66 %\"\r\n\"P1\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\r\n\"P1\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\"\r\n"
[DataObjectMethod(DataObjectMethodType.Select)]
public
DataTable PrognoseTableData()
{
DataTable dt;
using
(var parser =
new
GenericParserAdapter(
new
StringReader(
"\"Prognostyp\",\"Kvartal\",\"Utfall\",\"Prognos\",\"Kvartalssumma\",\"Referens\",\"Procent\"\n\"Budget\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\n\"Budget\",\"Q2\",\"85 173\",\"31 463\",\"116 636\",\"117 133\",\"-0,42 %\"\n\"Budget\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\n\"Budget\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\""
)))
{
parser.FirstRowHasHeader =
true
;
dt = parser.GetDataTable();
}
return
dt;
}