Exporting WinCC Unified Runtime Data to XLSX Spreadsheets
Engineers running SIMATIC WinCC Unified (TIA Portal V20) on Unified Panels (MTP) and PC Runtime stations frequently need to back up runtime tag values, recipe parameters, audit data, and trend archives to an external .xlsx file. Two production-grade paths exist in the V20 runtime API:
- Call
HMIRuntime.Device.SysFct.StartProgramfrom a JavaScript button or scheduled task to launch a headless spreadsheet process (LibreOffice / Calc / Writer) with a template and command-line arguments. - Use the integrated WinCC Unified Reporting engine to emit XLSX/PDF reports on a schedule, on tag change, or on event, with a designer-configured layout.
This reference walks through both methods, covers the V20.4 object model, the missing Program parameters documentation, template handling for the StartProgram path, and the field-proven caveats that come up when commissioning on a real MTP panel.
1. Overview of the Two Export Paths
| Aspect | StartProgram + LibreOffice | WinCC Unified Reporting |
|---|---|---|
| Configuration surface | JavaScript + button / scheduler | Report designer in TIA Portal |
| Output format | Any (XLSX, ODS, DOCX, ODT, PDF) | XLSX, PDF, optional CSV |
| Template support | Yes – load .xlsx/.ods then macro/UNO | Yes – layout templates |
| Headless execution | Possible with soffice --headless | Native, runs in Runtime service |
| Authentication / role gating | Manual in script | Built-in user administration |
| Best fit | Custom operator workflow, third-party toolchains | Compliance, audit, scheduled archives |
| Available since | V16 (API stable through V20) | V17 (significantly extended in V20) |
2. Prerequisites
2.1 Software versions
- TIA Portal V20 (Update 4 or later recommended; V20.4 referenced in this guide)
- WinCC Unified Runtime V20.4 on the target panel or PC
- SIMATIC WinCC Unified Scout / Engineering for report templates
- For Method 1 only: LibreOffice 7.4+ (headless Calc + a macro) installed on the Unified Panel or on a reachable Windows host
2.2 Hardware targets
| Device class | Tested with | Notes |
|---|---|---|
| Unified Comfort Panel | MTP1500, MTP1900, MTP2200 | Needs /home writable; USB for export |
| Unified PC Runtime | IPC227G, IPC677E, standard Win10 IoT | Full LibreOffice install supported |
| Open Controller | ET 200SP Open Controller | PC Runtime variant only |
2.3 Filesystem preparation
The runtime needs a writable target directory. On a Unified Panel, the conventional paths are:
/home/industrial/Reports/ # persistent, survives reboot on most panels
/media/sd-mmc-complete/Reports/ # SD card path, recommended for archives
/hmi/ # non-persistent (lost on reboot)
Create the folder from the engineering project under Runtime settings → File system or via the panel's service menu.
3. Method 1: HMIRuntime.Device.SysFct.StartProgram
3.1 The StartProgram signature in V20
The function is part of the JavaScript runtime API of WinCC Unified. The full signature as documented in the V20 object model reference:
HMIRuntime.Device.SysFct.StartProgram(
Program : String, // path to executable
ProgramParameters : String, // command-line arguments (single string)
WindowMode : UInt32, // 0 = hidden, 1 = normal, 2 = minimized, 3 = maximized
WaitForProgramEnd : Boolean,
OperatingMode : UInt32, // 0 = run once, 1 = wait for completion
OnAsyncError : Function // callback for errors
) : UInt32; // returns process handle / 0 on error
The reference page sysfct.startprogram-rt-unified deliberately keeps the description of ProgramParameters terse. Empirically, the string is forwarded to the OS exactly as written; the runtime does not parse it. That gives full control but also full responsibility: quoting, escaping, and path separators are your problem.
3.2 Plain "save my data" pattern (CSV / XLSX)
You cannot pass tag values as command-line arguments in a single call — the parameter string is one literal block. The accepted pattern is:
- Pre-write the data the engine cares about (tag values, timestamps) to a
.csvor.txtfile usingHMIRuntime.FileSystemor the file system tags. - Invoke StartProgram to launch LibreOffice with a macro that opens a base template, pulls in the data file, and exports to
.xlsx.
3.3 Step-by-step: Launch LibreOffice headless with a macro
Step 1 — Stage the data file. Use the file system API from a button script:
// Stage runtime values to a CSV the macro will consume
const path = "/home/industrial/Reports/inbox/params_" + Date.now() + ".csv";
let csv = "Tag;Value;Timestamp\n";
csv += "Motor1.Speed;" + HMIRuntime.Tags("Motor1_Speed").Read() + ";" + new Date().toISOString() + "\n";
csv += "Motor1.Current;" + HMIRuntime.Tags("Motor1_Current").Read() + ";" + new Date().toISOString() + "\n";
csv += "Conveyor.Speed;" + HMIRuntime.Tags("Conveyor_Speed").Read() + ";" + new Date().toISOString() + "\n";
HMIRuntime.FileSystem.WriteFile(path, csv, "utf-8");
Step 2 — Prepare the LibreOffice macro. Create ImportParams.bas in ~/.config/libreoffice/4/user/Scripts/Basic/Standard/ on the runtime host:
Sub ImportParams(sInCsv As String, sTemplate As String, sOutXlsx As String)
Dim oDoc As Object
Dim oArgs(0) As New com.sun.star.beans.PropertyValue
oArgs(0).Name = "Hidden"
oArgs(0).Value = True
oDoc = StarDesktop.loadComponentFromURL(ConvertToURL(sTemplate), "_blank", 0, oArgs())
oDoc.getSheets().getByIndex(0).getCellByPosition(0,0).setString("Imported " & Now())
oDoc.storeToURL(ConvertToURL(sOutXlsx), Array())
oDoc.close(True)
End Sub
Step 3 — Build the command string. LibreOffice's headless macro runner uses the macro:/// URI:
const sOffice = "/usr/bin/soffice"; // adjust per panel
const sMacro = "macro:///Standard.ImportParams.ImportParams("
+ '"' + csvPath + '",'
+ '"' + templatePath + '",'
+ '"' + xlsxOutPath + '")';
const sCmd = sOffice + ' --headless --norestore --nologo ' + sMacro;
HMIRuntime.Device.SysFct.StartProgram(
sOffice,
sCmd.substring(sOffice.length + 1), // strip the executable, keep args
0, // hidden
true, // wait for completion
0, // run once
function(err) { console.log("StartProgram err=" + err); }
);
Step 4 — Wire it to a button or scheduler. In the HMI screen, drop a button and assign the script above. For periodic archival, bind a Scheduled task in the TIA project to a global script that performs the same write + StartProgram sequence.
3.4 Using a base file as a template
Templates work through the same mechanism. Two practical options:
| Option | Mechanism | When to use |
|---|---|---|
| A — Load template, then macro edits cells | Pass the template path to loadComponentFromURL and let the macro fill it |
Rich formatting, formulas, charts |
B — Use LibreOffice's --convert-to xlsx with a template via mailmerge |
Pre-stage data, run a one-shot conversion | Simple bulk export, no formulas |
Option A is the only one that supports per-record placement into named cells (e.g. A4 = Motor1.Speed, B4 = Motor1.Speed.Value). The template itself can include logos, header cells, formulas, and conditional formatting that survive the macro write because storeToURL preserves the file's cell styles, not just values.
3.5 Quoting pitfalls (field-proven)
- Filenames with spaces must be wrapped in
"…"inside theProgramParametersstring. Use single quotes inside the JS template string to avoid escaping hell. - On Windows runtime, the executable is
soffice.exeunderC:\Program Files\LibreOffice\program\. Quote it:"C:\Program Files\LibreOffice\program\soffice.exe". - The runtime strips a leading
"if the entire parameter string begins with one. Pass the executable and arguments in two calls or strip quotes in the JS layer first. -
--headlessrequires a writableuserprofile. On a locked-down panel, set-env:UserInstallation=file:///tmp/lo_profile.
4. Method 2: WinCC Unified Reporting (recommended)
For parameter backups, audit logs, and batch sheets, the V20 WinCC Unified Reporting component is purpose-built. It runs inside the Runtime service (not as a child process) and outputs XLSX without any external dependency.
4.1 Enable Reporting in the project
- Open the TIA Portal project.
- Select the Unified HMI device → Properties → Runtime settings → Reporting.
- Tick Activate Reporting.
- Define a storage path (e.g.
/home/industrial/Reports/) and a naming scheme such asParamBackup_<yyyyMMdd_HHmmss>.xlsx.
4.2 Create a report template
- In the project tree, right-click Reports → Add new report.
- Choose the Online variant for runtime data (tag values) or Historical for archived tags.
- Insert a Table element and bind it to a tag collection, an alarm log, or an archive.
- Configure columns, filters, and time ranges. The V20.4 designer supports dynamic parameter binding via Parameter sets.
4.3 Trigger the report from JavaScript
Reports can be triggered three ways: time-based, event-based, or from a script using the Reporting API. The scripting call is the V20 equivalent of legacy Print/Archive:
// Trigger a pre-built report on demand from a button
const oReport = HMIRuntime.Report("ParamBackup_Report");
oReport.Trigger(
{
storagePath: "/home/industrial/Reports/",
fileName: "ParamBackup_" + new Date().toISOString().replace(/[:.]/g,"-") + ".xlsx",
format: "xlsx"
},
function(success) {
if (success) HMIRuntime.Trace("Report generated");
else HMIRuntime.Trace("Report failed");
}
);
Trigger() vary slightly between V17, V18 and V20. Always confirm against the V20.4 object model in your local help install (Help → Show help → Object model).4.4 Storage quotas and rotation
A Unified Panel SD card is typically 4–32 GB. A tag-based report with 1,000 records runs about 60–120 kB; a 5-minute cadence over a year yields roughly 60–70 MB. Set up a cleanup script:
// Delete reports older than 30 days
const folder = "/home/industrial/Reports/";
const now = Date.now();
HMIRuntime.FileSystem.GetFolder(folder).then(items => {
items.forEach(f => {
if (now - f.dateModified > 30*24*3600*1000 && f.name.endsWith(".xlsx"))
HMIRuntime.FileSystem.DeleteFile(folder + f.name);
});
});
5. Comparison: Choosing the Right Method
| Criterion | StartProgram path | Reporting path |
|---|---|---|
| Effort to first report | Medium (4–8 h incl. macro) | Low (1–2 h, designer only) |
| Reusable templates | Manual file handling | Built-in versioning in TIA project |
| Runtime overhead | Spikes (LibreOffice start ~600 MB RAM) | Constant, low (~50 MB) |
| Panel / PC support | PC runtime strongly recommended | Both panel and PC |
| Data integrity guarantees | None (you handle retries) | Built-in retry + log |
| Ability to embed operator edits | Yes (LibreOffice open in normal mode) | No (export only) |
6. Verification Procedure
After configuring either method, run this checklist before sign-off:
- Trigger the export manually from the panel and confirm a file appears in the configured path.
- Open the XLSX on a workstation and verify column order, value types, and time stamps match the runtime.
-
Check the Runtime log (WinCC Unified RT log / syslog). Look for entries
HMIRuntime: StartProgram returned 0(Method 1) orReport job … completed(Method 2). - Reboot the panel and confirm the scheduled job resumes. Reports that use a startup task should appear within one cycle.
- Force a power loss mid-write on a test unit. Confirm no half-written file remains in the target folder (Reporting path uses atomic temp-file rename; StartProgram path may leave <name>.~lock).
- Permission test: log in as an operator with restricted rights and confirm the export button is role-gated (use the Authorization property of the button).
7. Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| StartProgram returns non-zero, no file | LibreOffice not installed or path wrong | Verify which soffice on the runtime host; install libreoffice-calc
|
| Process starts but macro not found | Macro not in user profile | Place ImportParams.bas in user/Scripts/Basic/Standard/, restart soffice |
| XLSX contains only template values, runtime values missing | Data file was not written before StartProgram | Add WaitForProgramEnd = false for data write, then sync via --wait flag on soffice |
| Report job stuck in Pending | Runtime user has no write permission on target path | Grant the Siemens TIA User account write rights; check SELinux / AppArmor on Linux panels |
| File shows '###' in date columns | Column width too small in template | Set a fixed width in the template or set Auto-fit in report designer |
| Number values displayed as text | CSV delimiter mismatch with locale | Force ; as separator; configure locale to English (US) on the panel |
| Export succeeds on PC, fails on panel | Panel uses read-only file system root | Always write under /home/industrial/ or /media/sd-mmc-complete/
|
| StartProgram hangs the UI | Called from a synchronous event handler | Move to a button click or scheduled task; do not use screen-load |
8. Performance & Sizing Notes
Use the following rule-of-thumb numbers for sizing the storage and CPU load:
- Approx. row size (XLSX): 60–120 bytes per record when tags are numeric, 200–400 bytes when strings are included.
- Approx. report file size (N tags, M samples): bytes ≈ 50 KB header + (N × M × 80 B).
Example sizing calculation for a 200-tag process with 10-minute logging, retained 90 days:
Samples per day = 24 × 6 = 144
Records per day = 200 × 144 = 28,800
Bytes per day = 28,800 × 80 + 50,000 ≈ 2.35 MB
Storage for 90 days ≈ 211 MB
Confirm the SD card class on the panel: Class 10 / U1 minimum, U3 recommended for write bursts during archive flushes.
9. Security Considerations
- Tag values may contain business-sensitive information. Restrict the export directory with POSIX ACLs:
chmod 750 /home/industrial/Reports. - Disable the ReadTags API for the operator role if they are not supposed to bulk-read values.
- If the XLSX leaves the panel (FTP, USB), apply the panel's Audit Trail configuration so the export event is logged.
- For Reporting, the V20 service writes an MD5 sidecar (
.md5) next to the XLSX for integrity checks; verify it downstream.
10. Example: Combined Pattern (Scheduled + Manual)
The cleanest architecture is to use Reporting for the background schedule and StartProgram for the interactive "Save as…" button the operator uses after a recipe change.
- Reporting job runs every 15 minutes, appending or rotating the XLSX.
- Button "Save snapshot now" calls StartProgram with the current tag values and a macro that exports a single user-named file.
- Both write to subfolders
/Reports/auto/and/Reports/manual/for easy review.
11. References in the Local Help
When working offline, these are the right entry points in the TIA Portal V20 help:
- Visualizing processes → WinCC Unified → Configuring reports
- Visualizing processes → WinCC Unified → Scripting → JavaScript reference → HMIRuntime → Device → SysFct → StartProgram
- Visualizing processes → WinCC Unified → System functions → File system functions
For the most current online object model, see the StartProgram object model page referenced at the start of this guide.
12. Frequently Asked Questions
Can WinCC Unified write directly to a LibreOffice Calc file at runtime?
Not via a native, documented API. You must stage the data to an intermediate file (CSV/TXT) and either call StartProgram with a LibreOffice macro that opens a template and exports to XLSX, or use the integrated Reporting component which writes XLSX natively without LibreOffice.
Where do I find the parameters of HMIRuntime.Device.SysFct.StartProgram in TIA V20?
The official entry point is the TIA Portal help: Visualizing processes → WinCC Unified → Scripting → JavaScript reference → HMIRuntime → Device → SysFct → StartProgram. Online, use the V20 object model page. The method takes the executable path, the command-line string, the window mode, a wait flag, the operating mode, and an error callback.
Can I use a base XLSX as a template for the export?
Yes. Pass the template path to LibreOffice's loadComponentFromURL from a macro, fill the cells, and call storeToURL with the target XLSX. Styles, formulas, and charts in the template are preserved. The Reporting path has its own layout templates managed inside the TIA project.
Does this work on a Unified Comfort Panel, or only on PC Runtime?
Reporting works on both panels and PC Runtime. The StartProgram + LibreOffice path works on PC Runtime comfortably and on the larger Unified Panels (MTP1900 / MTP2200), but smaller panels may not have the disk or RAM for LibreOffice. Test with a representative load before committing.
How do I avoid an operator being able to read all tag values via the export button?
Apply the standard WinCC Unified authorization model: assign an Authorization (e.g. Maintenance) to the button on the screen. Users without the role see the button greyed out. Combined with the panel's user administration and an audit-trail configuration, every export attempt is logged in the RT log.