I have odd even pages for each record that I have to prepare report. when I run the MVC application i can see the XtraReport Viewer but there are no pages in it.
Controller/Action Logic
var xtraReport1 = XtraReport.FromStream(GenerateStreamFromString(layout1), true);
var xtraReport2 = XtraReport.FromStream(GenerateStreamFromString(layout2), true);
var finalExtraReport = new XtraReport();
foreach(var row in dataTable.Rows)
{
xtraReport1 = XtraReport.FromStream(GenerateStreamFromString(layout1), true);
xtraReport1.DataSource = dataTable.Select("id = '"+ row[id] +"'")CopyToDataTable();
xtraReport1.CreateDocument();
finalExtraReport.Pages.AddRange(xtraReport1.Pages);
xtraReport2 = XtraReport.FromStream(GenerateStreamFromString(layout2), true);
xtraReport2.DataSource = dataTable.Select("id = '"+ row[id] +"'")CopyToDataTable();
xtraReport2.CreateDocument();
finalExtraReport.Pages.AddRange(xtraReport2.Pages);
}
return View(finalExtraReport);
View
#model XtraReport
#{
ViewBag.Title = "Home Page";
}
#Html.DevExpress().WebDocumentViewer(settings =>
{
settings.Name = "webDocumentViewer";
}).Bind(Model).GetHtml()
Found the solution.
This behavior is caused by the fact that the WebDocumentViewer extension recreates the report document to preview it. So, the report pages added to your report dynamically will be cleared.
Currently, when using the HTML5 Document Viewer control to preview a report, it is necessary to call the XtraReport.AfterPrint event handler to merge report pages. So, handle your "r2" report's AfterPrint event and use this event handler to add the "r1" report's pages to the "r2" report.
public ActionResult ShowReport()
{
//...
XtraReport mainReport = //get a report;
mainReport.AfterPrint += Report_AfterPrint;
//...
}
void Report_AfterPrint(object sender, EventArgs e) {
//merge reports
XtraReport sourceReport = sender as XtraReport;
XtraReport additionalReport = new XtraReport1();
additionalReport.CreateDocument();
sourceReport.Pages.AddRange(additionalReport.Pages);
}
Note : starting with version 15.2.5 WebDocumentViewer supports displaying merged reports out of the box.
Related
I want to show a list on an .aspx site. Therefore I have to use the SP client object model.
I found the following tutorial, but this doesn't use the client libraries:
http://social.technet.microsoft.com/wiki/contents/articles/30287.binding-gridview-with-sharepoint-list.aspx
My code so far looks the following:
ClientContext clientContext = GetContext(accessToken);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
// Get the email input list.
List inboxList = web.Lists.GetByTitle("InboxList");
Microsoft.SharePoint.Client.ListItemCollection items = inboxList.GetItems(new CamlQuery());
clientContext.Load(inboxList);
clientContext.Load(items, ic => ic.Include(i => i["DisplayName"], i => i["Client_Title"], i => i["HasUniqueRoleAssignments"]));
clientContext.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.ListItem i in items)
{
clientContext.Load(i);
}
clientContext.ExecuteQuery();
oGrid.DataSource = items;
oGrid.DataBind();
But this shows only some "meta data" of the list item collection, see screenshot:
If I use oGrid.DataSource = inboxList; I get an InvalidOperationException because the data source isn't type of IListSource, IEnumerable nor IDataSource.
If I use oGrid.DataSource = inboxList.DataSource; I get an PropertyOrFieldNotInitializedException, but I don't know how to load this attribute (via clientContext.Load it didn't work)?!
I got it - works with following code:
protected void Page_Load(object sender, EventArgs e)
{
...
ClientContext clientContext = GetContext(accessToken);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
// Get the email input list.
List inboxList = web.Lists.GetByTitle("InboxList");
Microsoft.SharePoint.Client.ListItemCollection items = inboxList.GetItems(new CamlQuery());
clientContext.Load(inboxList);
clientContext.Load(items);
clientContext.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.ListItem i in items)
{
clientContext.Load(i);
}
clientContext.ExecuteQuery();
oGrid.DataSource = GetInboxListData(inboxList, items);
oGrid.DataBind();
}
else if (!IsPostBack)
{
Response.Write("Could not find a context token.");
return;
}
}
private DataTable GetInboxListData(List inboxList, Microsoft.SharePoint.Client.ListItemCollection items)
{
DataTable dt = new DataTable();
dt.Columns.Add("From");
dt.Columns.Add("To");
dt.Columns.Add("Subject");
dt.Columns.Add("Body");
dt.Columns.Add("Attachments");
dt.Columns.Add("Sent");
DataRow row;
foreach(Microsoft.SharePoint.Client.ListItem item in items)
{
row = dt.Rows.Add();
row["From"] = item["From1"].ToString();
row["To"] = item["To"].ToString();
row["Subject"] = item["Subject1"].ToString();
row["Body"] = item["Body1"].ToString();
row["Attachments"] = item["Attachments"].ToString();
row["Sent"] = item["Sent"].ToString();
}
return dt;
}
This is similar to Retrieve the values from a list to Gridview in SharePoint Webpart? but with client object model methods & objects.
I created a master report file. Then I created subreport file. Is there a way to put xml code of the subreport file as a report source ?
Override OnBeforePrint method and go through XtraReportBase.Controls property tree to find XRSubreport. As described here you can use DataSet and its DataSet.ReadXml method:
protected override void OnBeforePrint(PrintEventArgs e)
{
base.OnBeforePrint(e);
//Get your xml here
var dataSet = new DataSet();
using (var reader = new StringReader(xml))
dataSet.ReadXml(reader);
SetSubReportXML(this, dataSet);
}
private void SetSubReportXML(XRControl xrControl, DataSet dataSet)
{
foreach (XRControl xrControlChild in xrControl.Controls)
{
var subReport = xrControlChild as XRSubreport;
if (subReport != null)
{
//Set your xml here
subReport.ReportSource.DataSource = dataSet;
subReport.ReportSource.DataMember = this.DataMember;
SetSubReportXML(subReport.ReportSource, dataSet);
}
SetSubReportXML(xrControlChild, dataSet);
}
}
I'm looking for a way to print ASP.NET/ Mono MVC2 view from ASP.NET application running in Windows 2003 server.
I tried code below based on Programmatically "hello world" default SERVER-side printer in ASP.NET MVC
but this outputs raw html string. How to print view as formatted text using free software?
Order layout is created as html partial view. If there is other free way to print out formatted order, I can create layout in other form instead of html.
Only free solution which I have found requires to use Windows Forms WebBrowser control but this looks not reasonable in MVC2 application which is running under Mono also.
I looked into Rotativa ( http://nuget.org/packages/Rotativa/ ) but it looks like it doesnt allow to print html.
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Web.Mvc;
public class PrintController : Controller
{
string body;
public ActionResult Complete()
{
body = RenderViewToString<TestOrder>("~/Views/Checkout/Order.ascx", new TestOrder() { Number = "1" });
PrintOrder();
return View("PaymentComplete");
}
void PrintOrder()
{
// https://stackoverflow.com/questions/12229823/programmatically-hello-world-default-server-side-printer-in-asp-net-mvc
var doc = new PrintDocument();
doc.PrinterSettings.PrinterName = "HP Laserjet 1200";
doc.PrintPage += new PrintPageEventHandler(ProvideContent);
doc.Print();
}
void ProvideContent(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString(body,
new Font("Arial", 12),
Brushes.Black,
e.MarginBounds.Left,
e.MarginBounds.Top);
}
string RenderViewToString<T>(string viewPath, T model)
{ // https://stackoverflow.com/questions/483091/render-a-view-as-a-string
ViewData.Model = model;
using (var writer = new StringWriter())
{
var view = new WebFormView(viewPath);
var vdd = new ViewDataDictionary<T>(model);
var viewCxt = new ViewContext(ControllerContext, view, vdd, new TempDataDictionary(), writer);
viewCxt.View.Render(viewCxt, writer);
return writer.ToString();
}
}
}
public class TestOrder
{
public string Number;
}
There is an article about convert HTML to PDF using iTextSharp: http://www.dotnetspider.com/resources/43589-How-convert-HTML-PDF-ASP-NET.aspx
I have deployed a user control on sharepoint 2007 list Edit.aspx page. It is working fine on my test server but on production only the UI of the user control is loaded. No textbox or combo box on page load are getting filled. Please see the screen shot of default values of user control instead of the filled up data. Also find the code below which takes the ID from querystring and loads the required data on page load. I have used createdby value to check who is assigning the list item. If the user is accessing the data which is not created by him then its redirected to other page.Please guide me. What shall I do or check to make it work.
public partial class Class1 : System.Web.UI.UserControl
{
static string name, lname, Number;
protected void Page_Load(object sender, EventArgs e)
{
try
{
string c1,c2,c3,c4,c5, Created;
if (!Page.IsPostBack)
{
EditID = Convert.ToInt32(Request.QueryString["ID"]);
name = SPContext.Current.Web.CurrentUser.Name;
lname = SPContext.Current.Web.CurrentUser.LoginName;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("site name"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["list1"];
SPList UserSkill = web.Lists["list2"];
ItemForEdit = UserSkill.GetItemById(EditID);
c1 = ItemForEdit["col1"].ToString();
c2 = ItemForEdit["col2"].ToString();
c3 = ItemForEdit["col3"].ToString();
c4 = ItemForEdit["col4"].ToString();
c5 = ItemForEdit["col5"].ToString();
Created = ItemForEdit["Author"].ToString();
Number = ItemForEdit["col6"].ToString();
string[] extract;
extract = Created.Split('#');
if (name == extract[1])
{
WholeData = web.Lists["list1"].Items.GetDataTable();
Roles = WholeData.DefaultView.ToTable(true, "Title");
txtnumber.Text = Number;
ddlRole.DataSource = Roles;
ddlRole.DataTextField = "Title";
ddlRole.DataValueField = "Title";
ddlRole.DataBind();
ddlRole.SelectedValue = c1;
//more code
}
else
{
Response.Redirect("/IM/pages/Intrusion.aspx", false);
}
}
}
});
}
}
catch (Exception exc)
{
HttpContext.Current.Response.Write("<script>alert('Exception on page load: " + exc.Message + "')</script>");
}
}
}
It looks at first cut to be a data issue.
To debug on your production box you can use a remote debugger, or you could add a call that checks if 0 items are returned and either product an error or log the result.
I am developing a sharepoint 2007 web part that uses custom properties. Here is one:
[Personalizable(PersonalizationScope.User), WebDisplayName("Policy Update List Name")]
[WebDescription("The name of the SharePoint List that records all the policy updates.\n Default value is Policy Updates Record.")]
public string PolicyUpdateLogName
{
get { return _PolicyUpdateLogName == null ? "Policy Updates Record" : _PolicyUpdateLogName; }
set { _PolicyUpdateLogName = value; }
}
The properties work fine except that the changes are not reflected in the web part until you leave the page and navigate back (or just click on the home page link). Simply refreshing the page doesn't work, which makes me think it has something to do with PostBacks.
My current theory is that the ViewState is not loading postback data early enough for the changes to take effect. At the very least, the ViewState is involved somehow with the issue.
Thanks,
Michael
Here is more relevant code:
protected override void CreateChildControls()
{
InitGlobalVariables();
FetchPolicyUpdateLog_SPList();
// This function returns true if the settings are formatted correctly
if (CheckWebPartSettingsIntegrity())
{
InitListBoxControls();
InitLayoutTable();
this.Controls.Add(layoutTable);
LoadPoliciesListBox();
}
base.CreateChildControls();
}
...
protected void InitGlobalVariables()
{
this.Title = "Employee Activity Tracker for " + PolicyUpdateLogName;
policyColumnHeader = new Literal();
confirmedColumnHeader = new Literal();
pendingColumnHeader = new Literal();
employeesForPolicy = new List<SPUser>();
confirmedEmployees = new List<SPUser>();
pendingEmployees = new List<SPUser>();
}
...
// uses the PolicyUpdateLogName custom property to load that List from Sharepoint
private void FetchPolicyUpdateLog_SPList()
{
site = new SPSite(siteURL);
policyUpdateLog_SPList = site.OpenWeb().GetList("/Lists/" + PolicyUpdateLogName);
}
...
protected void InitListBoxControls()
{
// Init ListBoxes
policies_ListBox = new ListBox(); // This box stores the policies from the List we loaded from SharePoint
confirmedEmployees_ListBox = new ListBox();
pendingEmployees_ListBox = new ListBox();
// Postback & ViewState
policies_ListBox.AutoPostBack = true;
policies_ListBox.SelectedIndexChanged += new EventHandler(OnSelectedPolicyChanged);
confirmedEmployees_ListBox.EnableViewState = false;
pendingEmployees_ListBox.EnableViewState = false;
}
...
private void LoadPoliciesListBox()
{
foreach (SPListItem policyUpdate in policyUpdateLog_SPList.Items)
{
// Checking for duplicates before adding.
bool itemExists = false;
foreach (ListItem item in policies_ListBox.Items)
if (item.Text.Equals(policyUpdate.Title))
{
itemExists = true;
break;
}
if (!itemExists)
policies_ListBox.Items.Add(new ListItem(policyUpdate.Title));
}
}
Do some reading up on the Sharepoint web part life cycle. Properties are not updated until the OnPreRender event.