Spotfire Automation Xlsx DataWriter - spotfire

I was wondering if anybody here attempted creating an Automation Service to Export a DataTable to Xlsx in Spotfire Automation Services? I have been trying to create one but I am having issues. If anybody has been able to do this can you please share your project?
THis is the code I have thus far but having issues with Accessing the DataSource and DataTable.
protected override TaskExecutionStatus ExecuteCore(TaskExecutionContext context)
{
DataRowReader dataRowReader;
///Create a DataWriter
DataWriter writer = context.Application.CreateDataWriter(DataWriterTypeIdentifiers.ExcelXlsDataWriter);
///<summary>
///Call the DataWriter Core from here or call a class that will do the relevant work
///<toDO>Need to find a way to access the current DataTable of the Open Analysis</toDo>
///</summary>
Document doc = context.Application.Document;
if(doc == null)
return new TaskExecutionStatus(false, "NoAnalysisLoaded");
DataManager data = doc.Context.GetService<DataManager>();
DataTable table = data.Tables.Add(doc.ActiveDataTableReference, dataSource);
string fileName = context.ExpandTags(this.filePath);
FileStream fs = File.OpenWrite(fileName);
//See how to properly impliment the writers
writer.Write(fs, table, new IndexSet(table.RowCount, true), table.Columns.Names);
fs.Close();
data.Tables.Remove(table);
return new TaskExecutionStatus(true);
}

To get the active data table reference you should use
DataTable mytable = Application.Document.ActiveDataTableReference;
and then you can use mytable further in the code.

Related

Attachments Overrides existing while adding from VendorMaint graph

I am importing data and documents from third party application into Acumatica.
After importing, I am creating Vendor dynamically using below code along with attachments.
VendorMaint graph = PXGraph.CreateInstance<VendorMaint>();
VendorR row1 = null;
row1 = new VendorR();
row1.AcctName = VendorName;
row1.NoteID = noteid; // Existing - GUID created while importing
graph.BAccount.Update(row1);
If attachment already exists then it should update instead of duplicating.
In this case if Vendor already exists with files attached, then my code overrides these attachments and remove all previous files attached to that existing vendor.
I want to add the attachment instead of override the existing attachment. Any suggestion?
Try to use insert method of view:
VendorMaint graph = PXGraph.CreateInstance<VendorMaint>();
var row1 = new VendorR();
row1 = graph.BAccount.Insert(row1);
if (row1 == null) // already inserted or wasn't able to insert
{
//some logic with newly created vendor
}
else
{
//some logic with existed
}
row1.AcctName = "vendor name";
row1.NoteID = noteid; // Existing - GUID created while importing
graph.BAccount.Update(row1);
I have found the solution for the issue. Below code helps to create a new attachment and does not override any existing attachments for an existing Vendor.
// Getting the FileID of the attached file from DACClass
UploadFile uf = PXSelectJoin<UploadFile,
InnerJoin<NoteDoc, On<NoteDoc.fileID, Equal<UploadFile.fileID>>,
InnerJoin<DACClass, On<DACClass.noteID, Equal<NoteDoc.noteID>>>>,
Where<DACClass.noteID, Equal<Required<DACClass.noteID>>>>.Select(this, noteid);
if (uf != null)
{
PXNoteAttribute.SetFileNotes(graph.BAccount.Cache, graph.BAccount.Current, uf.FileID.Value);
NoteDoc doc = new NoteDoc();
doc.NoteID = uf.FileID.Value;
doc.FileID = new Guid();
graph.BAccount.Cache.Insert(doc);
}

Exception when open excel: File contains corrupted data

I am trying to read an excel with OpenXML.
What I did is simply as following:
private WorkbookPart wbPart = null;
private SpreadsheetDocument document = null;
public byte[] GetExcelReport()
{
byte[] original = File.ReadAllBytes(this.originalFilename);
using (MemoryStream stream = new MemoryStream())
{
stream.Write(original, 0, original.Length);
using (SpreadsheetDocument excel = SpreadsheetDocument.Open(stream, true))
{
this.document = excel;
this.wbPart = document.WorkbookPart;
UpdateValue();
}
stream.Seek(0, SeekOrigin.Begin);
byte[] data = stream.ToArray();
return data;
}
}
I initialized this.originalFilename in the constructor. It is the filename ended with '.xlsx' which i created with excel 2010.
But this line of code
using (SpreadsheetDocument excel = SpreadsheetDocument.Open(stream, true))
gives the exception: Message: System.IO.FileFormatException: File contains corrupted data.
The StackTrace:
Does anyone know how to solve this problem? At the beginning, I didn't use the Stream, I just use SpreadsheetDocument.Open(filename, true). However, it turns out to be exactly the same exception.
I've tried to create a new .xlsx file, but it's still the same.
There is a MSDN page which describes the process of reading and writing Excel file using stream and open xml SDK.
http://msdn.microsoft.com/en-us/library/office/ff478410.aspx
Try extracting the document contents through zip application and check whether you are getting the standard folders inside like xl,docProps and _rels etc.,
This is a method to find whether the package is properly packaged as archive or not.
Hope this helps.

How do I use a linq query as a datasource for TreeView or GridView

I am trying to find a way to use the result from my linq query as a datasource for a TreeView and GridView in C#, without having to save the file first in the server. Have tried various options, but all require that the document is saved as a file first. Can someone please help me out? The code is given below:
XDocument products = new XDocument(
new XDeclaration("1.0", "utf-8", ""),
new XElement("products",
new XElement("product", new XAttribute("id", "p1"),
new XElement("name", "Alpha"),
new XElement("Address", "200 WATERLOO DRIVE"),
new XElement("price",
new XElement("currency", "Rs.")),
new XElement("stock", "19"),
new XElement("country", "USA",
new XElement("state", "California"))),
new XElement("product", new XAttribute("id", "p2"),
new XElement("name", "Beta"),
new XElement("Address", "500 MOUNTBATTEN AVENUE"),
new XElement("price",
new XElement("currency", "Rs.")),
new XElement("stock", "25"),
new XElement("country", "USA",
new XElement("state", "Florida")))));
//create a linq query
var newxml = from f1 in products.Elements("product")
where (string)f1.Element("country").Element("state") != "Florida"
select f1;
//Create an xml document in memory using the linq query
XDocument xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", ""),
new XElement("products"));
xdoc.Element("products").Add(newxml);
//create a datasource for TreeView or GridView using the xml document in memory.
XmlDataSource xmlds = new XmlDataSource();
xmlds.DataFile=xdoc;
TreeView1.DataSource = xmlds;
TreeView1.DataBind();
GridView1.DataSource = xmlds;
GridView1.DataBind();
The part of the code for creating the datasource from xdoc is not working. It can be made to work by saving the file and then calling the file for the datasource, but I want do do this from the memory.
you can use the linq query result directly as datasource.
gridview1.datasource = newxml;
gridview1.databind();
drawback i have encountered is that for e.g sorting to work you will need to implement own sort method.

Displaying Managed Property in Search Results - FAST Search for Sharepoint 2010

We are working with Fast Search for Sharepoint 2010 and had some backend setup done with creating some managed properties e.g. BestBetDescription, keywords etc.
From the front-end part we are creating an application what will fetch all these properties and display in a grid.
However while querying the backend we are NOT getting these managed properties (BestBetDescription) along with other properties such as Title, URL etc.
Following is my source code:
settingsProxy = SPFarm.Local.ServiceProxies.GetValue<SearchQueryAndSiteSettingsServiceProxy>();
searchProxy = settingsProxy.ApplicationProxies.GetValue<SearchServiceApplicationProxy>("FAST Query SSA");
keywordQuery = new KeywordQuery(searchProxy);
keywordQuery.EnableFQL = true;
keywordQuery.QueryText = p;
keywordQuery.ResultsProvider = SearchProvider.FASTSearch;
keywordQuery.ResultTypes = ResultType.RelevantResults;
ResultTableCollection resultsTableCollection = keywordQuery.Execute();
ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];
DataTable resultsDataTable = new DataTable();
resultsDataTable.TableName = "Results";
resultsDataTable.Load(searchResultsTable, LoadOption.OverwriteChanges);
return resultsDataTable;
The results are returned and I cannot see the Managed properties which we create in the resultDataTable.
Is there any property I missed or is this a backend issue ?
Thanks.
Hi if you are creating your custom Metadata Property then u should use this option to be selected
please check below link
http://screencast.com/t/SQdlarjhx4F
You can find this option in :
central admin:- services :- fast search :- Metadata Property :- your property
I was missing a property KeywordQuery.SelectProperties
So the code looks something like this
String[] arrSearchProperties = new String[] { "Title", "body", "url" };
KeywordQuery.SelectProperties(arrSearchProperties);
This will fetch you all the Managed Properties defined by you.

Programmatically Edit Infopath Form Fields?

I have a form library in my share point site. Programmatically I need to fill some fields. Can I do that? If any one know please provide me some sample code. First I need to retrieve the infopath document and then I need to fill the fields.
What axel_c posted is pretty dang close. Here's some cleaned up and verified working code...
public static void ChangeFields()
{
//Open SharePoint site
using (SPSite site = new SPSite("http://<SharePoint_Site_URL>"))
{
using (SPWeb web = site.OpenWeb())
{
//Get handle for forms library
SPList formsLib = web.Lists["FormsLib"];
if (formsLib != null)
{
foreach (SPListItem item in formsLib.Items)
{
XmlDocument xml = new XmlDocument();
//Open XML file and load it into XML document
using (Stream s = item.File.OpenBinaryStream())
{
xml.Load(s);
}
//Do your stuff with xml here. This is just an example of setting a boolean field to false.
XmlNodeList nodes = xml.GetElementsByTagName("my:SomeBooleanField");
foreach (XmlNode node in nodes)
{
node.InnerText = "0";
}
//Get binary data for new XML
byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xml.OuterXml);
using (MemoryStream ms = new MemoryStream(xmlData))
{
//Write data to SharePoint XML file
item.File.SaveBinary(ms);
}
}
}
}
}
}
The Infopath document is just a regular XML file, the structure of which matches the data sources you defined in the Infopath form.
You just need to access the file via the SharePoint object model, modify it using standard methods (XmlDocument API) and then write it back to the SharePoint list. You must be careful to preserve the structure and insert valid data or you won't be able to open the form using Infopath.
You should really check out a book on SharePoint if you plan to do any serious development. Infopath is also a minefield.
Object model usage examples: here, here and here. The ridiculously incomplete MSDN reference documentation is here.
EDIT: here is some example code. I haven't done SharePoint for a while so I'm not sure this is 100% correct, but it should give you enough to get started:
// Open SharePoint site
using (SPSite site = new SPSite("http://<SharePoint_Site_URL>"))
{
using (SPWeb web = site.OpenWeb())
{
// Get handle for forms library
SPList formsLib = web.Lists["FormsLib"];
if (formsLib != null)
{
SPListItem itm = formsLib.Items["myform.xml"];
// Open xml and load it into XML document
using (Stream s = itm.File.OpenBinary ())
{
MemoryStream ms;
byte[] xmlData;
XmlDocument xml = new XmlDocument ();
xml.Load (s);
s.Close ();
// Do your stuff with xml here ...
// Get binary data for new XML
xmlData = System.Text.Encoding.UTF8.GetBytes (xml.DocumentElement.OuterXml);
ms = new MemoryStream (xmlData);
// Write data to sharepoint item
itm.File.SaveBinary (ms);
ms.Close ();
itm.Update ();
}
}
web.Close();
}
site.Close();
}
It depends a bit on your available tool set, skills and exact requirements.
There are 2 main ways of pre populating data inside an InfoPath form.
Export the relevant fields as part of the form's publishing process. The fields will then become columns on the Document / Forms library from where you can manipulate them either manually, via a Workflow or wherever your custom code is located.
Directly manipulate the form using code similar to what was provided by Axel_c previously. The big question here is: what will trigger this code? An event receiver on the Document Library, a SharePoint Designer Workflow, a Visual Studio workflow etc?
If you are trying to do this from a SharePoint Designer workflow then have a look at the Workflow Power Pack for SharePoint. It allows C# and VB code to be embedded directly into the workflow without the need for complex Visual Studio development. An example of how to query InfoPath data from a workflow can be found here. If you have some development skills you should be able to amend it to suit your needs.
I also recommend the site www.infopathdev.com, they have excellent and active forums. You will almost certainly find an answer to your question there.
Thanks for the sample code, #axel_c and #Jeff Burt
Below is just the same code from Jeff Burt modified for a file in Document set which I needed. If you don't already have the Document Set reference, you can check out this site on how to grab one:
http://howtosharepoint.blogspot.com/2010/12/programmatically-create-document-set.html
Also, the codes will open the .xml version of the infopath form and not the .xsn template version which you might run into.
Thanks again everyone...
private void ChangeFields(DocumentSet docSet)
{
string extension = "";
SPFolder documentsetFolder = docSet.Folder;
foreach (SPFile file in documentsetFolder.Files)
{
extension = Path.GetExtension(file.Name);
if (extension != ".xml") //check if it's a valid xml file
return;
XmlDocument xml = new XmlDocument();
//Open XML file and load it into XML document, needs to be .xml file not .xsn
using (Stream s = file.OpenBinaryStream())
{
xml.Load(s);
}
//Do your stuff with xml here. This is just an example of setting a boolean field to false.
XmlNodeList nodes = xml.GetElementsByTagName("my:fieldtagname");
foreach (XmlNode node in nodes)
{
node.InnerText = "xyz";
}
//Get binary data for new XML
byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xml.OuterXml);
using (MemoryStream ms = new MemoryStream(xmlData))
{
//Write data to SharePoint XML file
file.SaveBinary(ms);
}
}
}
I had this issue and resolved it with help from Jeff Burt / Axel_c's posts.
I was trying to use the XMLDocument.Save([stream]) and SPItem.File.SaveBinary([stream]) methods to write an updated InfoPath XML file back to a SharePoint library. It appears that XMLDocument.Save([stream]) writes the file back to SharePoint with the wrong encoding, regardless of what it says in the XML declaration.
When trying to open the updated InfoPath form I kept getting the error "a calculation in the form has not been completed..."
I've written these two functions to get and update and InfoPath form. Just manipulate the XML returned from ReadSPFiletoXMLdocument() in the usual way and send it back to your server using WriteXMLtoSPFile().
private System.Xml.XmlDocument ReadSPFiletoXMLdocument(SPListItem item)
{
//get SharePoint file XML
System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
try
{
using (System.IO.Stream xmlStream = item.File.OpenBinaryStream())
{
xDoc.Load(xmlStream);
}
}
catch (Exception ex)
{
//put your own error handling here
}
return xDoc;
}
private void WriteXMLtoSPFile(SPListItem item, XmlDocument xDoc)
{
byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xDoc.OuterXml);
try
{
using (System.IO.MemoryStream outStream = new System.IO.MemoryStream(xmlData))
{
item.File.SaveBinary(outStream);
}
}
catch (Exception ex)
{
//put your own error handling here
}
}

Resources