# System.file.writeFile issue with Perspective

**URL:** <https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229>\
**Category:** Ignition Early Access\
**Created:** [April 18, 2019, 1:05pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229 "2019-04-18T13:05:22Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [April 18, 2019, 1:05pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/1 "2019-04-18T13:05:22Z")

</div>

This is probably a documentation issue.

[https://docs.inductiveautomation.com/display/DOC80/system.file.writeFile](https://docs.inductiveautomation.com/display/DOC80/system.file.writeFile)

[https://docs.inductiveautomation.com/display/DOC80/system.file.saveFile](https://docs.inductiveautomation.com/display/DOC80/system.file.saveFile)

When I try to use the code snippet from the documentation (in Perspective) it tells me that saveFile isn’t an attribute of system.file. If I use the ctrl+space suggestions of system.file from a button’s onClick event in Perspective there is no saveFile method. The code examples show using saveFile to create the file and then system.file.writeFile to write to the file.

It’s been a few years since I wrote to a file from Ignition so I don’t remember how it’s supposed to work.

Ultimately, I’m just trying to export data from historical tag data to a .csv. I’m starting with the “easy stuff” so I’m just trying to write a text string to a file.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 18, 2019, 1:34pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/2 "2019-04-18T13:34:19Z")

</div>

saveFile doesn’t actually save a file. It opens a file chooser dialog looking at the local filesystem to allow the user to construct a file path+name. That string is the return value. It only works in Vision because browsers don’t permit this kind of action.

writeFile is then used to actually perform the save operation. Again, it only works (locally) in Vision because browsers don’t permit this kind of action. The alternative in Perspective is to construct a downloadable file first, then place a link to it in your view. Following that link uses the browser’s download mechanism, which may or may not automatically offer a dialog to select a location and name to save under.

Perspective is fundamentally different from Vision. This is one of those differences.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [April 18, 2019, 2:22pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/3 "2019-04-18T14:22:14Z")

</div>

To add onto @pturmel’s response, please look at the available scopes for the functions you’re attempting to use; `saveFile()` is only available in Vision Client scripting - not Perspective Sessions.

The `writeFile()` function IS available in Perspective, but ALL functions in Perspective run on the Gateway (so that’s where the file is written to), so you will never see a file on your local machine as a result of using `writeFile()`.

There’s no mechanism in Perspective as of today that allows for exporting or downloading files of any type - short of coupling with the WebDev Module.

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [April 18, 2019, 3:01pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/4 "2019-04-18T15:01:22Z")

</div>

@pturmel  
Thanks for the clarification. I vaguely remember that from training now that you mention it.

@cmallonee I saw your other response on this about the file being saved on the server. It threw me a bit when I tried to use the example from the help and it blew up. The scope makes sense.

I was having trouble getting it to accept my path. I had to escape “” in my path. It’s been a while since I did this and after figure out the problem it was kinda obvious. It’s not every year I have to write to a file from an HMI.

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [April 18, 2019, 5:52pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/5 "2019-04-18T17:52:13Z")

</div>

I figured out a pretty good solution for what I need to do. The customer wants to be able to select data points and have them displayed in a grid. Then they want to be able to hit a button to download a CSV file of the data from the grid.

This code got it done:  
dataset = self.getSibling(“Table”).props.data  
export = system.dataset.toCSV(dataset, 1, 0, 0)  
system.perspective.download(filename=“test.csv”, data=export)

system.perspective.download isn’t documented on the official documentation yet. I found it on the intellisence thing and poked it until it worked.

Of course, selecting data points to display on the grid is the next fun challenge. I suspect this code will export all datapoints in the dataset whether I have them hidden or not.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [April 18, 2019, 7:29pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/6 "2019-04-18T19:29:41Z")

</div>

It’s not documented because no one here knows about it (the dev who placed it is out right now). I’ll request it be added to the documentation.

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [April 18, 2019, 7:40pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/7 "2019-04-18T19:40:56Z")

</div>

Thanks. This was a dumb luck situation.

I appreciate your help as always. I have been developing better stuff in general thanks to your help. I’m still using some of the stuff you showed me to muddle my way through unrelated things. My general approach to developing Perspective projects has improved thanks to your feedback.

I also appreciate the feature. It is EXACTLY what I needed. So thumbs up to that developer also 🙂

---

<div class="post-metadata">

**Author:** ![craigb](https://avatars.discourse-cdn.com/v4/letter/c/9f8e36/32.png) [@craigb](https://forum.inductiveautomation.com/u/craigb)\
**Post date:** [August 6, 2019, 9:40am UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/8 "2019-08-06T09:40:21Z")

</div>

Is this an official way to save a table to CSV on the local machine ?

---

<div class="post-metadata">

**Author:** ![grietveld](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/grietveld/32/6984_2.png) [@grietveld](https://forum.inductiveautomation.com/u/grietveld)\
**Post date:** [August 6, 2019, 11:53am UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/9 "2019-08-06T11:53:36Z")

</div>

system.perspective.download is an official option. It just didn’t seem to be communicated to everyone when it rolled out.

Documentation can be found below.

[https://docs.inductiveautomation.com/display/DOC80/system.perspective.download](https://docs.inductiveautomation.com/display/DOC80/system.perspective.download)

---

<div class="post-metadata">

**Author:** ![craigb](https://avatars.discourse-cdn.com/v4/letter/c/9f8e36/32.png) [@craigb](https://forum.inductiveautomation.com/u/craigb)\
**Post date:** [August 6, 2019, 12:02pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/10 "2019-08-06T12:02:23Z")

</div>

That’s what I thought, but when i tried the code posted above on a table in my program it doesn’t work. So wasn’t sure if that was an official method.

I put the following code in a button script referencing a table.

```auto
dataset = self.getSibling(“Table”).props.data
export = system.dataset.toCSV(dataset, 1, 0, 0)
system.perspective.download(filename=“test.csv”, data=export)

```

The error in the gateway log shows…

```auto
org.python.core.PySyntaxError: SyntaxError: (u"no viable alternative at character '\u201c'", ('', 4, 38, u'\tsystem.perspective.download(filename=\u201ctest.csv\u201d, data=export)\n'))

at org.python.core.ParserFacade.fixParseError(ParserFacade.java:95)

at org.python.core.ParserFacade.parse(ParserFacade.java:205)

at org.python.core.Py.compile_flags(Py.java:2205)

at com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:841)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunctionSuper(ProjectScriptLifecycle.java:526)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.getOrCreateDelegate(ProjectScriptLifecycle.java:565)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.(ProjectScriptLifecycle.java:556)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunction(ProjectScriptLifecycle.java:515)

at com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:822)

at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:68)

at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:65)

at com.inductiveautomation.perspective.gateway.action.ActionDecorator.runAction(ActionDecorator.java:18)

at com.inductiveautomation.perspective.gateway.action.SecuredAction.runAction(SecuredAction.java:51)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:257)

at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:246)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:215)

at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.base/java.lang.Thread.run(Unknown Source)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 6, 2019, 1:10pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/11 "2019-08-06T13:10:53Z")

</div>

That’s a pure syntax error, not a problem with the logic. I can’t tell from your code block precisely what the problem is, but it isn’t a problem with system.perspective.download(). Possibly it is the paired quotation marks. You must use the straight quote marks in code.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [August 6, 2019, 1:58pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/12 "2019-08-06T13:58:41Z")

</div>

Or the fact that the variable `dataset` is a list, whereas the function call expects a Dataset.

---

<div class="post-metadata">

**Author:** ![anastasia.blinova](https://avatars.discourse-cdn.com/v4/letter/a/a698b9/32.png) [@anastasia.blinova](https://forum.inductiveautomation.com/u/anastasia.blinova)\
**Post date:** [June 9, 2021, 2:15pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/13 "2021-06-09T14:15:56Z")

</div>

I’m using Ignition version 8.1.4 and this method doesn’t seem to work anymore?

I put the following code in a button script referencing a table, similar to a post above:

```auto
dataset = self.getSibling("Table").props.data
csv = system.dataset.toCSV(dataset, showHeaders = True, forExport = False)
system.perspective.download(filename=“test.csv”, data=csv)

```

But on button press I get the following error:

```auto
Unable to run action 'component.onActionPerformed' on Main Views/TagHistory@D/root/Button: code could not be compiled.

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 9, 2021, 2:43pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/14 "2021-06-09T14:43:42Z")

</div>

That error generally means a syntax error. I see curly quotes in your code’s third line around `test.csv`. Those should be ASCII straight double quotes. This commonly occurs when someone posts code without proper formatting marks, and this forum tries to “prettify” the “paragraphs”, like here. Don’t cut and paste from improperly formatted code on forums.

---

<div class="post-metadata">

**Author:** ![anastasia.blinova](https://avatars.discourse-cdn.com/v4/letter/a/a698b9/32.png) [@anastasia.blinova](https://forum.inductiveautomation.com/u/anastasia.blinova)\
**Post date:** [June 9, 2021, 2:49pm UTC](https://forum.inductiveautomation.com/t/system-file-writefile-issue-with-perspective/24229/15 "2021-06-09T14:49:09Z")

</div>

You’re completely right. Thank you.
