Friday, May 31, 2013

Save PerformancePoint Analytic Reports to SharePoint

Save PerformancePoint Analytic Reports to SharePoint


These are the steps of how to save a "navigated" PerformancePoint Analytic Reports as a custom view into SharePoint programmatically and reference it later .

1. Get the report Id from the client side.

When a PerformancePoint Analytic Report is "navigated" from the default view, there is a custom report created with a newly assigned ID. By referencing this new ID, you can save the custom report into SharePoint.

From JavaScript:

    var webPartRecords = PPSMA.ClientConnectionManager.get_instance().get_connectionManagerRecord().WebPartRecords;

The returned objec collection "webPartRecords" contains object "webPartRecord". This object has "ClientId" which you can use to locate the PPS web part on page and "recordId" which you can use to save the report. The recordId is retrieved from the ViewState F775B8BE98A540C2AB08B34D53460E4B.

var lastReportId = wP.ViewState["F775B8BE98A540C2AB08B34D53460E4B"];

2. Once you have the reportId, pass it to the server side code and save the report.

ReportView report = BIMonitoringServiceApplicationProxy.Default.GetAnalyticReportView(new RepositoryLocation(new Guid(reportId)));
ReportView newReport = SPDataStore.GlobalDataStore.CreateReportView(listUrl, report);

Tuesday, May 14, 2013

Download Item Attachment and Upload it To Document Library

Download List Item Attachment and Upload it To Document Library
(with SharePoint Server Object Model and Client Object Model)

Purpose:

Migrate file attachments of SharePoint list item to SharePoint document library on the same server (Server Object Model) or on different servers (Client Object Model).

Server Object Model:

Using server object model, the code is relatively easy. The sample code assume there is one attachment file per list item.

        private void MigrateFile(SPWeb fromWeb, SPWeb toWeb, string fromListTitle, string toListTitle)
        {
            SPList fromList = fromWeb.Lists.TryGetList(fromListTitle);
            SPList toList = toWeb.Lists.TryGetList(toListTitle);
 
            if (fromList != null && toList != null)
            {
                foreach (SPListItem fromItem in fromList.Items)
                {  
                    string fromFileName = fromItem.Attachments[0];
                    SPFile fromFile = fromWeb.GetFile(fromItem.Attachments.UrlPrefix + fromFileName);
 
                    string toFileName = toList.RootFolder.ServerRelativeUrl + "/" + fromItem.Title + ".xml";
                    fromFile.CopyTo(toFileName, true);
                }
            }
        }

Client Object Model:

Using client object model you can migrate file between servers remotely. It is more flexible than server side object model but a little bit more difficult to write. For each sample code, you can easily write more code to copy the properties of the file too.

                ClientContext fromContext = new ClientContext("http://from.server.com");
                ClientContext toContext = new ClientContext("http://to.server.com");
 
                Web fromWeb = fromContext.Site.OpenWebById(fromWebInfo.Id);
                List fromList = fromWeb.Lists.GetById([listID]); //your own ID here
 
                // find the attachments folder of the list
                fromContext.Load(fromList, l => l.RootFolder.Folders.Where(f => f.Name == "Attachments"));
                fromContext.ExecuteQuery();
 
                if (fromList.RootFolder.Folders.Count > 0)
                {
                    // there is only one Attachments folder
                    Folder attachmentFolder = fromList.RootFolder.Folders[0];
 
                    fromContext.Load(attachmentFolder, f => f.Folders);
                    fromContext.ExecuteQuery();
 
                    foreach (Folder itemFolder in attachmentFolder.Folders)
                    {
                        FileCollection files = itemFolder.Files;
                        fromContext.Load(files);
                        fromContext.ExecuteQuery();
 
                        // assume there should be only one file in the special case
                        // Loop throught each file if there more than one
                        if (files.Count > 0)
                        {
                            Microsoft.SharePoint.Client.File file = files[0];
 
                            //download
                            FileInformation fromFileInfo = File.OpenBinaryDirect(fromContext, file.ServerRelativeUrl);
 
                            string fileUrl = "[ServerRelativeUrlOnTargetServer] + [filename.extension]"// your code here
 
                            //upload
                            File.SaveBinaryDirect(toContext, fileUrl, fromFileInfo.Stream, true);
                        }
                    }
                }