I want to upload excel file and show the content of uploaded excel file data grid. Everything is going well. But when i convert the the content in the form of byteArray in excel sheet format with the help of loadFromByteArray() function then system is giving me error as "Cannot access a property or method of a null object reference".
Here is my code to upload excel content:
protected function browseExcelFile(event:MouseEvent):void
{
excFileRef = new FileReference();
excFileRef.addEventListener(Event.SELECT, onSelect);
excFileRef.addEventListener(Event.COMPLETE, onComplete);
var fileFilter:FileFilter = new FileFilter("Excel (.xls)", "*.xls");
excFileRef.browse([fileFilter]);
}
private function onSelect(event:Event):void {
excelFileName.text = excFileRef.name;
excFileRef.load();
}
private function onComplete(event:Event):void {
excelFileName.text = excFileRef.name;
exceldataInByte = new ByteArray();
exceldataInByte = event.currentTarget.data;
if(exceldataInByte.length > 0){
var excObj:ExcelFile = new ExcelFile();
excObj.loadFromByteArray(exceldataInByte); /* this line give error */
var sheet:Sheet = excObj.sheets[0];
}
}
I dont know why this error occuring, i have searched on many sites but everywhere everyone posted the same way as i have done to upload excel but my code gives me error.
Please tell me why this error occur?
EDIT: After viewing this preview (http://activetuts.s3.amazonaws.com/tuts/169_as3xls/1/preview.html) I realized that this excel import tool only works with spreadsheets who only have 2 columns of data, regardless of how many columns your datagrid has. After trying to load an .xls file of only two columns into my own test app, it is working as expected.
I believe I recreated your error.
Here is the line that threw the error:
excObj.loadFromByteArray(exceldataInByte); /* this line give error */
Here is the error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.as3xls.xls::ExcelFile/dimensions()[/...com/as3xls/xls/ExcelFile.as:619]
at Function/http://adobe.com/AS3/2006/builtin::call()
at com.as3xls.xls::ExcelFile/loadFromByteArray()[/...com/as3xls/xls/ExcelFile.as:309]
at stackoverflow/onComplete()[C:\...\src\stackoverflow.mxml:47]
Here is the line which is throwing the error in the swc (line 619): https://code.google.com/p/as3xls/source/browse/trunk/src/com/as3xls/xls/ExcelFile.as#619
I suggest you checkout the source code into your workspace from here (https://code.google.com/p/as3xls/source/checkout), and debug to find what is broken.
Related
My team is working on an Office 365 add-in for Excel, and as part of the project, we’re creating Excel documents through the GraphAPI with the end goal of having the add-in already setup for the document. We’re using the .NET OpenXml library to create the document before copying it through the GraphAPI.
We haven’t been able to find many resources for how to setup an add-in through OpenXml and have not been able to get anything working. The last thing we tried was copying the example we found here, but we couldn’t get it working. Does anyone know how to setup add-ins using the OpenXml library?
Note: the add-in is already in the Office Add-Ins store, and we have information like the AppSource ID.
Thank you!
We're actually about to publish a new sample around this scenario. The sample shows how to create an Excel document using OOXML, embed your add-in, and then upload the file to OneDrive. It also creates a Team chat that links to the file.
You can try out the sample here: Open data from your web site in a spreadsheet in Microsoft Teams
Or give us feedback on the PR: https://github.com/OfficeDev/PnP-OfficeAddins/pull/197
To answer your question about how to embed the add-in, you need to create a web extension section. I've copied the relevant code here. Note this is the same code from the Office-OOXML-EmbedAddin sample you already looked at. We reused it for the new sample. You can change the CUSTOM MODIFICATION section to provide any custom properties you want to your add-in when it opens.
// Embeds the add-in into a file of the specified type.
private void EmbedAddin(SpreadsheetDocument spreadsheet)
{
spreadsheet.DeletePart(spreadsheet.WebExTaskpanesPart);
var webExTaskpanesPart = spreadsheet.AddWebExTaskpanesPart();
CreateWebExTaskpanesPart(webExTaskpanesPart);
}
// Adds child parts and generates content of the specified part.
private void CreateWebExTaskpanesPart(WebExTaskpanesPart part)
{
WebExtensionPart webExtensionPart1 = part.AddNewPart<WebExtensionPart>("rId1");
GenerateWebExtensionPart1Content(webExtensionPart1);
GeneratePartContent(part);
}
// Generates content of webExtensionPart1.
private void GenerateWebExtensionPart1Content(WebExtensionPart webExtensionPart1)
{
// Add web extension containg Id for Script Lab add-in
We.WebExtension webExtension1 = new We.WebExtension() { Id = "{635BF0CD-42CC-4174-B8D2-6D375C9A759E}" };
webExtension1.AddNamespaceDeclaration("we", "http://schemas.microsoft.com/office/webextensions/webextension/2010/11");
// Add store information for Script Lab add-in
We.WebExtensionStoreReference webExtensionStoreReference1 = new We.WebExtensionStoreReference() { Id = "wa104380862", Version = "1.1.0.0", Store = "en-US", StoreType = "OMEX" };
We.WebExtensionReferenceList webExtensionReferenceList1 = new We.WebExtensionReferenceList();
We.WebExtensionPropertyBag webExtensionPropertyBag1 = new We.WebExtensionPropertyBag();
// Add the property that makes the taskpane visible.
We.WebExtensionProperty webExtensionProperty1 = new We.WebExtensionProperty() { Name = "Office.AutoShowTaskpaneWithDocument", Value = "true" };
webExtensionPropertyBag1.Append(webExtensionProperty1);
// CUSTOM MODIFICATION BEGIN
// Add the property that specifies the snippet to import.
string snippetToImportValue = string.Format("{{\"type\":\"gist\",\"id\":\"{0}\"}}", "{72189570-AE11-4207-9DEE-C8BDE4B83188}");
We.WebExtensionProperty webExtensionProperty2 = new We.WebExtensionProperty() { Name = "SnippetToImport", Value = snippetToImportValue };
webExtensionPropertyBag1.Append(webExtensionProperty2);
// CUSTOM MODIFICATION END
We.WebExtensionBindingList webExtensionBindingList1 = new We.WebExtensionBindingList();
We.Snapshot snapshot1 = new We.Snapshot();
snapshot1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtension1.Append(webExtensionStoreReference1);
webExtension1.Append(webExtensionReferenceList1);
webExtension1.Append(webExtensionPropertyBag1);
webExtension1.Append(webExtensionBindingList1);
webExtension1.Append(snapshot1);
webExtensionPart1.WebExtension = webExtension1;
}
// Generates content of part.
private void GeneratePartContent(WebExTaskpanesPart part)
{
Wetp.Taskpanes taskpanes1 = new Wetp.Taskpanes();
taskpanes1.AddNamespaceDeclaration("wetp", "http://schemas.microsoft.com/office/webextensions/taskpanes/2010/11");
Wetp.WebExtensionTaskpane webExtensionTaskpane1 = new Wetp.WebExtensionTaskpane() { DockState = "right", Visibility = true, Width = 350D, Row = (UInt32Value)4U };
Wetp.WebExtensionPartReference webExtensionPartReference1 = new Wetp.WebExtensionPartReference() { Id = "rId1" };
webExtensionPartReference1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtensionTaskpane1.Append(webExtensionPartReference1);
taskpanes1.Append(webExtensionTaskpane1);
part.Taskpanes = taskpanes1;
}
I'm trying to use an SSIS script task to copy an excel file into a Sharepoint library when a file with the same name already exists there. It doesn't matter if it deletes the old file first then copies the new or just copies and replaces the new. I can't figure out how to delete the old file and it won't copy the new until the old is gone. So far I have:
/*
Microsoft SQL Server Integration Services Script Task
Write scripts using Microsoft Visual C# 2008.
The ScriptMain is the entry point class of the script.
*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
namespace ST_be5f0817a6b54483a96a8c9e79402175.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
/*
The execution engine calls this method when the task executes.
To access the object model, use the Dts property. Connections, variables, events,
and logging features are available as members of the Dts property as shown in the following examples.
To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value;
To post a log entry, call Dts.Log("This is my log text", 999, null);
To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true);
To use the connections collection use something like the following:
ConnectionManager cm = Dts.Connections.Add("OLEDB");
cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;";
Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
To open Help, press F1.
*/
public void Main()
{
string fileDir = (string)Dts.Variables["fileDir"].Value;
string SPDir = (string)Dts.Variables["SPDir"].Value;
if (File.Exists(Path.Combine(SPDir, "filename.CSV")))
{
File.Delete(Path.Combine(SPDir, "filename.CSV"));
}
File.Copy(Path.Combine(fileDir, "filename.CSV"), Path.Combine(SPDir, "filename.CSV"));
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
I think I can delete the file by running a data flow component with the sharepoint list connector before the script and have the script just copy the file over, but I'm trying to avoid that many components and connections and that method just generally sounds more complicated.
Any help or advice would be welcome.
Fixed this issue by changing the relevant line to: File.Copy(Path.Combine(fileDir, "filename.CSV"), Path.Combine(SPDir, "filename.CSV"), true);
The boolean argument specifies whether to overwrite the existing file and is "false" if not specified.
I am trying to get a reference to a File object using the File.openDlg() method using Extendscript, but when I do this it only seems to allow me to select a specific file type. I want the dialog to allow me to open any type of file. When I use File.openDialog() I am able to select any file type, but because I am launching the OS specific file chooser when a modal dialog button is clicked, it causes the open file chooser to keep popping up--I don't know why it keeps looping, but I suspect it has to do with the "modalness" of the dialog that is currently up when the method is called. So, I am left with simply using the File.openDlg() method, but I don't understand how to inform the MacOS to allow a user to select any file type.
In Adobe's documentation the signature for the .openDlg method is as follows:
fileObj.OpenDlg ([prompt][,filter][,multiSelect])
Then it specifies that the [filter] paramter is:
In Mac OS, a filter function that takes a File instance and returns true if the file
should be included in the display, false if it should not.
So, because I do not want any filetype masking I call the method like so:
newFootageSrc.openDlg("Select your file", function(file) {return true;}, false);
This doesn't work, so I found older Adobe documentation where this was specified for the [filter] param:
In Mac OS, a string containing the name of a function defined in the current
JavaScript scope that takes a File object argument. The function is called
foreach file about to be displayed in the dialog, and the file is displayed
only whenthe function returns true
So, I simply made a named function like this
function allFileTypesOSX(file){ return true; }
And then referenced allFileTypesOSX in the method call like this:
newFootageSrc.openDlg("Select your file", "allFileTypesOSX", false);
That didn't work, so I thought maybe just passing in the identifier itself rather than string would do the trick:
newFootageSrc.openDlg("Select your file", allFileTypesOSX, false);
But alas, that didn't work. Has anybody successfully been able to control file types in the MacOS dialog using ExtendScript?
I know I have this working in scripts at home, so I'll double check the syntax I use when I get home, but I do something along these lines (I'm supporting both windows and mac users).
var fileMask;
if(isWindows()) fileMask = '*.psd';
if(isMac()) fileMask = function(file){file.name.match(/\.psd$/i) ? true:false;}
var files = File.openDialog ('prompt', fileMask, true);
Its more similar to original attempt - you should be passing the actual filter function, not its name.
ETA: If you're not trying to actually limit the selectable files - have you tried just passing null, or leaving the parameter out altogether? They are all optional.
ETA: actual code from a working script (for Photoshop, works in CS3+). By 'works' I mean users on macs are able to select the files they need. I don't have a mac myself to actually see what they see. In a different script I found the following comment to myself above the isSupported function: 'returns true or false depending on if file is a png. 'Filter' doesn't seem to be working right on macs so this is a double check'. If the filter function isn't working as per the documentation this will definately be a problem for you when using the openDlg version of the method.
var filter;
if (isWindows()) {
filter = ["PNG:*.png"];
}
else {
filter = isSupported;
}
win.btnAdd.onClick = function() {
var f = File.openDialog("Open File", filter, false) ;
if (f == undefined)
return;
if (isSupported(f)) {
files = new Array();
files[0]=f;
win.lstImages.text = f.name;
methodInvoker.EnableControls();
} else {
alert("'" + decodeURI(f.name) + "' is an unsupported file.");
}
};
isSupported = function(file) {
try {
//macs will send a file or a folder through here. we need to respond true to folder to allow users to navigate through their directory structure
if (file instanceof Folder)
return true;
else
return file.name.match(/\.png$/i) != null;
} catch (e) {
alert("Error in isSupported method: " + e);
}
}
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.
I've created a snippet that pulls data from a databse table and displays it in tabular format. The snippet takes an id as parameter, and this is added to the sql query.
My problem is that if I've got more than 1 snippet call (sometimes need the tabular data for different id's displayed on a page) on the same page, all table data is the same as the last database call that's been made by the last snippet.
What do I need to do to kinda not cache the snippet database calls and have them all display their own content?
I've tried setting the page to no cache-able. Also used the [! !] brackets for the snippet calls, and even used the function_exists() method, but none of them helped.
Please can someone help me?
thanks
Try this at the end of the snippet:
mysql_connect('host', 'user', 'pass');
mysql_select_db('db_name');
You need to specify the connection parameters ofcourse.
It would help to answer if you can post your snippet. I do this with multiple calls on the page without issue, so there is either something wrong inside the snippet, or you need to output to unique placeholder names.
You have encountered a glitch of ModX, and it took me a long time to solve. ModX does a lot of caching by using hashing and apparently, when multiple connections are made from within one page divided over multiple snippets, this erratic behaviour can be seen. This is most likely very unwanted behaviour, it can be solved easily but gives you terrible headache otherways.
One sympton is that $modx->getObject($classname, $id)returns null (often).
The solution is very simple:
either use a static class with a single db instance, or
use $modx->setPlaceholder($instance, $tag);, or a combination.
My solution has been:
class dt__xpdo {
private function __construct() {}
public function __destruct() {
$this->close();
}
static public function db($modx = null) {
if ($modx->getPlaceholder('dt_xpdo') == '') {
$dt_user = 'xxxxxxxxx';
$dt_pw = 'xxxxxxxxx';
$dt_host = 'localhost';
$dt_dbname = 'xxxxxxxxx';
$dt_port = '3306';
$dt_dsn = "mysql:host=$dt_host;dbname=$dt_dbname;port=$dt_port;charset=utf8";
$dt_xpdo = new xPDO($dt_dsn, $dt_user, $dt_pw);
$dt_xpdo->setPackage('mymodel', MODX_CORE_PATH.'components/mymodel/'.'model/', '');
//$modx->log(modX::LOG_LEVEL_DEBUG, 'mymodel.config.php');
//$modx->log(modX::LOG_LEVEL_DEBUG, 'Could not addPackage for mymodel!');
$modx->setPlaceholder('dt_xpdo', $dt_xpdo);
}
return $modx->getPlaceholder('dt_xpdo');
}
}
Now you can use in your code:
require_once 'above.php';
and use something like
$xpdo = dt__xpdo::db($modx);
and continue flawlessly!