diff --git a/package-lock.json b/package-lock.json
index 9f12af07c5303924deb581b2cf12855cc20ee42a..5a2713b26c5e5a1165ba32394037b4d218277c0b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "nghyd",
-  "version": "1.1.0",
+  "version": "1.2.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -1634,6 +1634,15 @@
         "acorn": "^5.0.0"
       }
     },
+    "adler-32": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
+      "integrity": "sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=",
+      "requires": {
+        "exit-on-epipe": "~1.0.1",
+        "printj": "~1.1.0"
+      }
+    },
     "adm-zip": {
       "version": "0.4.13",
       "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz",
@@ -1693,6 +1702,7 @@
       "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
       "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
       "dev": true,
+      "optional": true,
       "requires": {
         "kind-of": "^3.0.2",
         "longest": "^1.0.1",
@@ -1704,6 +1714,7 @@
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
           "dev": true,
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
@@ -1840,6 +1851,7 @@
       "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
       "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
       "dev": true,
+      "optional": true,
       "requires": {
         "delegates": "^1.0.0",
         "readable-stream": "^2.0.6"
@@ -2757,6 +2769,17 @@
         "lazy-cache": "^1.0.3"
       }
     },
+    "cfb": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.1.0.tgz",
+      "integrity": "sha512-ZqfxNGWTMKhd0a/n6YKJLq8hWbd5kR3cA4kXwUj9vVEdHlwJ09werR8gN15Z7Y1FTXqdD6dE3GGCxv4uc28raA==",
+      "requires": {
+        "adler-32": "~1.2.0",
+        "commander": "^2.16.0",
+        "crc-32": "~1.2.0",
+        "printj": "~1.1.2"
+      }
+    },
     "chalk": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -3035,6 +3058,22 @@
         }
       }
     },
+    "codepage": {
+      "version": "1.14.0",
+      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
+      "integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
+      "requires": {
+        "commander": "~2.14.1",
+        "exit-on-epipe": "~1.0.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.14.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
+          "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
+        }
+      }
+    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -3088,8 +3127,7 @@
     "commander": {
       "version": "2.17.1",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
-      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
-      "dev": true
+      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
     },
     "commondir": {
       "version": "1.0.1",
@@ -3217,7 +3255,8 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
       "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "constants-browserify": {
       "version": "1.0.0",
@@ -3339,6 +3378,15 @@
         }
       }
     },
+    "crc-32": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
+      "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
+      "requires": {
+        "exit-on-epipe": "~1.0.1",
+        "printj": "~1.1.0"
+      }
+    },
     "create-ecdh": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
@@ -3653,7 +3701,8 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
       "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "depd": {
       "version": "1.1.2",
@@ -4215,6 +4264,11 @@
       "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
       "dev": true
     },
+    "exit-on-epipe": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
+      "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
+    },
     "expand-braces": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
@@ -4760,6 +4814,11 @@
       "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
       "dev": true
     },
+    "frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
+    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -4858,7 +4917,8 @@
         "ansi-regex": {
           "version": "2.1.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -4879,12 +4939,14 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -4899,17 +4961,20 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -5026,7 +5091,8 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -5038,6 +5104,7 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -5052,6 +5119,7 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -5059,12 +5127,14 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -5083,6 +5153,7 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -5163,7 +5234,8 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -5175,6 +5247,7 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -5260,7 +5333,8 @@
         "safe-buffer": {
           "version": "5.1.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -5296,6 +5370,7 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -5315,6 +5390,7 @@
           "version": "3.0.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -5358,12 +5434,14 @@
         "wrappy": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
@@ -5372,6 +5450,7 @@
       "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
       "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
       "dev": true,
+      "optional": true,
       "requires": {
         "graceful-fs": "^4.1.2",
         "inherits": "~2.0.0",
@@ -5384,6 +5463,7 @@
       "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
       "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
       "dev": true,
+      "optional": true,
       "requires": {
         "aproba": "^1.0.3",
         "console-control-strings": "^1.0.0",
@@ -5421,7 +5501,8 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
       "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "get-stream": {
       "version": "3.0.0",
@@ -5666,7 +5747,8 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "has-value": {
       "version": "1.0.0",
@@ -6513,7 +6595,8 @@
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
       "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "is-windows": {
       "version": "1.0.2",
@@ -7681,6 +7764,7 @@
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
       "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
       "dev": true,
+      "optional": true,
       "requires": {
         "graceful-fs": "^4.1.2",
         "parse-json": "^2.2.0",
@@ -7693,7 +7777,8 @@
           "version": "2.3.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
@@ -7802,7 +7887,8 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
       "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "loose-envify": {
       "version": "1.4.0",
@@ -7986,7 +8072,8 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
       "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
-      "dev": true
+      "dev": true,
+      "optional": true
     },
     "map-stream": {
       "version": "0.1.0",
@@ -8704,6 +8791,7 @@
       "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
       "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
       "dev": true,
+      "optional": true,
       "requires": {
         "are-we-there-yet": "~1.1.2",
         "console-control-strings": "~1.1.0",
@@ -9600,6 +9688,11 @@
       "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
       "dev": true
     },
+    "printj": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
+      "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
+    },
     "prismjs": {
       "version": "1.15.0",
       "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz",
@@ -9975,6 +10068,7 @@
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
       "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
       "dev": true,
+      "optional": true,
       "requires": {
         "load-json-file": "^1.0.0",
         "normalize-package-data": "^2.3.2",
@@ -9986,6 +10080,7 @@
           "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
           "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
           "dev": true,
+          "optional": true,
           "requires": {
             "graceful-fs": "^4.1.2",
             "pify": "^2.0.0",
@@ -9996,7 +10091,8 @@
           "version": "2.3.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
@@ -10005,6 +10101,7 @@
       "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
       "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
       "dev": true,
+      "optional": true,
       "requires": {
         "find-up": "^1.0.0",
         "read-pkg": "^1.0.0"
@@ -10015,6 +10112,7 @@
           "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
           "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
           "dev": true,
+          "optional": true,
           "requires": {
             "path-exists": "^2.0.0",
             "pinkie-promise": "^2.0.0"
@@ -10025,6 +10123,7 @@
           "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
           "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
           "dev": true,
+          "optional": true,
           "requires": {
             "pinkie-promise": "^2.0.0"
           }
@@ -11177,6 +11276,14 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
+    "ssf": {
+      "version": "0.10.2",
+      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.2.tgz",
+      "integrity": "sha512-rDhAPm9WyIsY8eZEKyE8Qsotb3j/wBdvMWBUsOhJdfhKGLfQidRjiBUV0y/MkyCLiXQ38FG6LWW/VYUtqlIDZQ==",
+      "requires": {
+        "frac": "~1.1.2"
+      }
+    },
     "sshpk": {
       "version": "1.16.1",
       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@@ -11360,6 +11467,7 @@
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
       "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
       "dev": true,
+      "optional": true,
       "requires": {
         "is-utf8": "^0.2.0"
       }
@@ -12801,6 +12909,7 @@
       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
       "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
       "dev": true,
+      "optional": true,
       "requires": {
         "string-width": "^1.0.2 || 2"
       }
@@ -12863,6 +12972,20 @@
         "ultron": "~1.1.0"
       }
     },
+    "xlsx": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.14.1.tgz",
+      "integrity": "sha512-7hjB5YuyJo1fuuzXQjwuxD8LSUzE4Rxu5ToC3fB5JSunZxGjLcgKg69bEFG9GYoxeVDx5GL0k1dUodlvaQNRQw==",
+      "requires": {
+        "adler-32": "~1.2.0",
+        "cfb": "^1.1.0",
+        "codepage": "~1.14.0",
+        "commander": "~2.17.1",
+        "crc-32": "~1.2.0",
+        "exit-on-epipe": "~1.0.1",
+        "ssf": "~0.10.2"
+      }
+    },
     "xml2js": {
       "version": "0.4.19",
       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
diff --git a/package.json b/package.json
index 77d7b5888f7620ff738500d9d9894f80ff68abec..bb1875351a7cd2f95737651be8ae0fd92da0f459 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "nghyd",
-  "version": "1.2.0",
+  "version": "4.0.0",
   "license": "MIT",
   "scripts": {
     "ng": "ng",
@@ -45,6 +45,7 @@
     "rxjs": "^6.3.3",
     "rxjs-compat": "^6.3.3",
     "tslib": "^1.9.0",
+    "xlsx": "^0.14.1",
     "zone.js": "^0.8.28"
   },
   "devDependencies": {
@@ -52,7 +53,7 @@
     "@angular/cli": "^7.2.2",
     "@angular/compiler-cli": "^7.2.1",
     "@angular/language-service": "^7.2.1",
-    "@compodoc/compodoc": "^1.1.7",
+    "@compodoc/compodoc": "^1.1.8",
     "@types/file-saver": "^2.0.0",
     "@types/jasmine": "^3.3.7",
     "@types/jasminewd2": "^2.0.6",
diff --git a/src/app/app.component.html b/src/app/app.component.html
index fbcfa67dbeadfe99ba0a0dc88d45bc44e1eaf537..134007e73fb72733da7467fb444d028cd18d9972 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -22,7 +22,7 @@
           <span class="calc-name">
             {{ currentCalc.title }}
           </span>
-          <span class="calc-type" [innerHTML]="'( ' + currentCalc ? currentCalc.type : '' + ' )'"></span>
+          <span class="calc-type" [innerHTML]="'(' + getCalculatorLabel(currentCalc.type) + ')'"></span>
         </button>
 
         <mat-menu #menu="matMenu" colo="accent">
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 542a55cdb830a07f55308c501476969b8ba3ed0c..acecbe6d6c16af6261b8478879d8b08402f9371a 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,5 +1,7 @@
 import { Component, ApplicationRef, OnInit, OnDestroy, HostListener, ViewChild, ComponentRef } from "@angular/core";
 import { Router, Event, NavigationEnd, ActivationEnd } from "@angular/router";
+import { MatSidenav, MatToolbar, MatDialog, MatIconRegistry } from "@angular/material";
+import { DomSanitizer } from "@angular/platform-browser";
 
 import { Observer, jalhydDateRev, CalculatorType } from "jalhyd";
 
@@ -14,7 +16,6 @@ import { HttpService } from "./services/http/http.service";
 import { ApplicationSetupService } from "./services/app-setup/app-setup.service";
 import { nghydDateRev } from "../date_revision";
 
-import { MatSidenav, MatToolbar, MatDialog } from "@angular/material";
 import { DialogConfirmEmptySessionComponent } from "./components/dialog-confirm-empty-session/dialog-confirm-empty-session.component";
 import { DialogLoadSessionComponent } from "./components/dialog-load-session/dialog-load-session.component";
 import { DialogSaveSessionComponent } from "./components/dialog-save-session/dialog-save-session.component";
@@ -69,7 +70,9 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     private httpService: HttpService,
     private confirmEmptySessionDialog: MatDialog,
     private saveSessionDialog: MatDialog,
-    private loadSessionDialog: MatDialog
+    private loadSessionDialog: MatDialog,
+    private matIconRegistry: MatIconRegistry,
+    private domSanitizer: DomSanitizer
   ) {
     ServiceFactory.instance.httpService = httpService;
     ServiceFactory.instance.applicationSetupService = appSetupService;
@@ -81,6 +84,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
       // close side navigation when clicking a calculator tab
       if (event instanceof NavigationEnd) {
         this.sidenav.close();
+        window.scrollTo(0, 0);
       }
       // [de]activate calc tabs depending on loaded route
       if (event instanceof ActivationEnd) {
@@ -93,6 +97,12 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
         }
       }
     });
+
+    // icônes personnalisées
+    this.matIconRegistry.addSvgIcon(
+      "file_excel",
+      this.domSanitizer.bypassSecurityTrustResourceUrl("../../assets/icons/file-excel.svg")
+    );
   }
 
   ngOnInit() {
diff --git a/src/app/components/calculator-results/calculator-results.component.html b/src/app/components/calculator-results/calculator-results.component.html
index 1cf1ee86e9e06e53a464453a59f86c8d0ae54081..03c60dfa0215f53ecd21ce647d72338d7715d427 100644
--- a/src/app/components/calculator-results/calculator-results.component.html
+++ b/src/app/components/calculator-results/calculator-results.component.html
@@ -1,5 +1,5 @@
-<div class="container-fluid">
-    <fixedvar-results></fixedvar-results>
+<div>
     <section-results></section-results>
     <remous-results></remous-results>
+    <fixedvar-results></fixedvar-results>
 </div>
diff --git a/src/app/components/fixedvar-results/fixed-results.component.html b/src/app/components/fixedvar-results/fixed-results.component.html
index b35f932d4c58789bd991bd20f33c13d0dd2ad727..1c2c8f0b4e4937432f1b9cd09e453700432123d2 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.html
+++ b/src/app/components/fixedvar-results/fixed-results.component.html
@@ -1,17 +1,26 @@
 <div class="fixed-results-container" *ngIf="hasFixedParameters">
+
+    <div class="fixed-results-buttons">
+        <button mat-icon-button (click)="exportAsSpreadsheet()">
+            <mat-icon color="primary" svgIcon="file_excel" class="scaled09"></mat-icon>
+        </button>
+    </div>
+
     <!-- table des résultats fixés -->
-    <table mat-table [dataSource]="dataSet">
+    <div class="fixed-results-inner-container" #tableContainer>
+        <table mat-table [dataSource]="dataSet">
 
-        <ng-container matColumnDef="parametre">
-            <th mat-header-cell *matHeaderCellDef>{{ uitextParamFixes }}</th>
-            <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.label }}</td>
-        </ng-container>
-        <ng-container matColumnDef="valeur">
-            <th mat-header-cell *matHeaderCellDef>{{ uitextValeurs }}</th>
-            <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.value }}</td>
-        </ng-container>
+            <ng-container matColumnDef="parametre">
+                <th mat-header-cell *matHeaderCellDef>{{ uitextParamFixes }}</th>
+                <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.label }}</td>
+            </ng-container>
+            <ng-container matColumnDef="valeur">
+                <th mat-header-cell *matHeaderCellDef>{{ uitextValeurs }}</th>
+                <td mat-cell *matCellDef="let element" [ngClass]="{'highlightedResult': element.isCalcResult}">{{ element.value }}</td>
+            </ng-container>
 
-        <tr mat-header-row *matHeaderRowDef="tableColumns"></tr>
-        <tr mat-row *matRowDef="let row; columns: tableColumns;"></tr>
-    </table>
+            <tr mat-header-row *matHeaderRowDef="tableColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: tableColumns;"></tr>
+        </table>
+    </div>
 </div>
diff --git a/src/app/components/fixedvar-results/fixed-results.component.scss b/src/app/components/fixedvar-results/fixed-results.component.scss
index 6884f3f370e00c829b993ac10a651536f736868c..5a8e48d7ad5cf2fc3ee75274b1dbd84f2fe3486f 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.scss
+++ b/src/app/components/fixedvar-results/fixed-results.component.scss
@@ -2,12 +2,29 @@
     display: block;
 }
 
-.fixed-results-container {
-    margin-top: 1em;
+.fixed-results-inner-container {
     border: solid #ccc 1px;
     border-radius: 2px;
 }
 
+.fixed-results-buttons {
+    padding-right: 4px;
+    padding-top: 4px;
+    text-align: right;
+    background-color: white;
+
+    button {
+        margin-left: 3px;
+        width: auto;
+
+        mat-icon {
+            &.scaled09 {
+                transform: scale(0.9);
+            }
+        }
+    }
+}
+
 table.mat-table {
 
     .mat-header-row {
@@ -15,7 +32,7 @@ table.mat-table {
     }
 
     .mat-row {
-        height: 32px;
+        height: auto;
 
         &:nth-child(odd) {
             background-color: #f4f4f4;
@@ -26,6 +43,11 @@ table.mat-table {
         font-size: 1em;
         color: black;
     }
+
+    ::ng-deep .mat-cell {
+        padding-top: 8px;
+        padding-bottom: 8px;
+    }
 }
 
 .highlightedResult {
diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts
index 4e97712b9f79d4c3999c8d76c70c7f77342b5b63..cf23921d8e5e41b06fc6c2346245b324a70e171d 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.ts
+++ b/src/app/components/fixedvar-results/fixed-results.component.ts
@@ -1,11 +1,11 @@
-import { Component, ViewChild } from "@angular/core";
+import { Component, ViewChild, ElementRef } from "@angular/core";
 
 import { FixedResults } from "../../results/fixed-results";
 import { NgParameter } from "../../formulaire/ngparam";
 import { CalculatorResults } from "../../results/calculator-results";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
-import { MatTable } from "@angular/material";
+import * as XLSX from "xlsx";
 
 @Component({
     selector: "fixed-results",
@@ -18,13 +18,13 @@ export class FixedResultsComponent {
     /** résultats non mis en forme */
     private _fixedResults: FixedResults;
 
-    @ViewChild(MatTable) table: MatTable<any>;
+    @ViewChild("tableContainer") table: ElementRef;
 
     public tableColumns = [ "parametre", "valeur" ];
 
     constructor(
         private intlService: I18nService,
-        private appSetupService: ApplicationSetupService,
+        private appSetupService: ApplicationSetupService
     ) { }
 
     public set results(r: FixedResults) {
@@ -80,12 +80,14 @@ export class FixedResultsComponent {
             && res.resultElement
             && res.extraResults
         ) {
-            // 2.1. main result
-            data.push({
-                label: this._fixedResults.calculatedParameterHeader,
-                value: this.intlService.formatResult(res.name, res.resultElement.vCalc),
-                isCalcResult: true // for CSS
-            });
+            // 2.1. main result (sometimes empty, for ex. in "Section paramétrée")
+            if (res.name && res.resultElement.vCalc) {
+                data.push({
+                    label: this._fixedResults.calculatedParameterHeader,
+                    value: this.intlService.formatResult(res.name, res.resultElement.vCalc),
+                    isCalcResult: true // for CSS
+                });
+            }
 
             // 2.2. extra results
             const extraResults = res.resultElement.extraResults;
@@ -102,4 +104,13 @@ export class FixedResultsComponent {
         }
         return data;
     }
+
+    public exportAsSpreadsheet() {
+        // automagic <table> extraction
+        const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement);
+        const wb: XLSX.WorkBook = XLSX.utils.book_new();
+        XLSX.utils.book_append_sheet(wb, ws, "default");
+        // save and download
+        XLSX.writeFile(wb, "FixedResults.xlsx");
+    }
 }
diff --git a/src/app/components/fixedvar-results/var-results.component.html b/src/app/components/fixedvar-results/var-results.component.html
index f89799dfd48f3e55d2f516df358b3ccf908c93a3..30d0afac88a20a45ad13f6c33b08af49de08ffb2 100644
--- a/src/app/components/fixedvar-results/var-results.component.html
+++ b/src/app/components/fixedvar-results/var-results.component.html
@@ -1,15 +1,31 @@
-<div class="var-results-container">
-    <!-- scrollable -->
-    <div class="var-results-inner-container">
+<div class="var-results-container" #variableResults *ngIf="hasResults" fxLayout="row wrap" fxLayoutAlign="center center">
+    <div fxFlex="1 1 100%">
+        <div class="var-results-buttons">
+            <button mat-icon-button (click)="exportAsSpreadsheet()">
+                <mat-icon color="primary" svgIcon="file_excel" class="scaled09"></mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(variableResults)">
+                <mat-icon color="primary" class="scaled12">fullscreen</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()">
+                <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon>
+            </button>
+        </div>
 
-        <table mat-table [dataSource]="dataSet">
-            <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h">
-                <th mat-header-cell *matHeaderCellDef>{{ h }}</th>
-                <td mat-cell *matCellDef="let element">{{ element[i] }}</td>
-            </ng-container>
+        <div class="var-results-scrollable-container" [ngClass]="{'full-height': isFullscreen}">
+            <!-- scrollable -->
+            <div class="var-results-inner-container" #tableContainer>
 
-            <tr mat-header-row *matHeaderRowDef="headers"></tr>
-            <tr mat-row *matRowDef="let row; columns: headers;"></tr>
-        </table>
+                <table mat-table [dataSource]="dataSet">
+                    <ng-container *ngFor="let h of headers; let i = index" [matColumnDef]="h">
+                        <th mat-header-cell *matHeaderCellDef>{{ h }}</th>
+                        <td mat-cell *matCellDef="let element">{{ element[i] }}</td>
+                    </ng-container>
+
+                    <tr mat-header-row *matHeaderRowDef="headers"></tr>
+                    <tr mat-row *matRowDef="let row; columns: headers;"></tr>
+                </table>
+            </div>
+        </div>
     </div>
 </div>
diff --git a/src/app/components/fixedvar-results/var-results.component.scss b/src/app/components/fixedvar-results/var-results.component.scss
index d8b8f970ea6ea458e1f1ccf4acccb0a6839af5f1..aa3f8ec31732183d2e4fdb2e588b2bbf9f19c5b2 100644
--- a/src/app/components/fixedvar-results/var-results.component.scss
+++ b/src/app/components/fixedvar-results/var-results.component.scss
@@ -3,9 +3,38 @@
 }
 
 .var-results-container {
-    overflow-x: scroll;
     margin-top: 2em;
+    background-color: white;
+}
+
+.var-results-buttons {
+    padding-right: 4px;
+    padding-top: 4px;
+    text-align: right;
+    background-color: white;
+
+    button {
+        margin-left: 3px;
+        width: auto;
+
+        mat-icon {
+            &.scaled12 {
+                transform: scale(1.2)
+            }
+            &.scaled09 {
+                transform: scale(0.9);
+            }
+        }
+    }
+}
+
+.var-results-scrollable-container {
+    overflow-x: scroll;
     border: solid #ccc 1px;
+
+    &.full-height {
+        height: calc(100vh - 40px); // rend le mode plein-écran scrollable verticalement, sinon ça dépasse
+    }
 }
 
 table.mat-table {
diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 7b8ca69eb196661c8d0b8619bf10bdad3c314aa2..37657da07f50469513321579049941de533367c0 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -1,10 +1,9 @@
-import { Component, ViewChild } from "@angular/core";
-import { MatTable } from "@angular/material";
+import { Component, ViewChild, ElementRef } from "@angular/core";
 import { VarResults } from "../../results/var-results";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { ResultElement } from "jalhyd";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
-import { nbind } from 'q';
+import * as XLSX from "xlsx";
 
 @Component({
     selector: "var-results",
@@ -24,7 +23,12 @@ export class VarResultsComponent {
     /** entêtes des colonnes (param à varier, à calculer + extraResults) */
     private _headers: string[];
 
-    @ViewChild(MatTable) table: MatTable<any>;
+    /** tracks the fullscreen state */
+    public get isFullscreen() {
+        return (document["fullscreenElement"] !== null);
+    }
+
+    @ViewChild("tableContainer") table: ElementRef;
 
     constructor(
         private appSetupService: ApplicationSetupService,
@@ -94,4 +98,21 @@ export class VarResultsComponent {
         }
         return data;
     }
+
+    public setFullscreen(element) {
+        element.requestFullscreen();
+    }
+
+    public exitFullscreen() {
+        document.exitFullscreen();
+    }
+
+    public exportAsSpreadsheet() {
+        // automagic <table> extraction
+        const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement);
+        const wb: XLSX.WorkBook = XLSX.utils.book_new();
+        XLSX.utils.book_append_sheet(wb, ws, "default");
+        // save and download
+        XLSX.writeFile(wb, "VariableResults.xlsx");
+    }
 }
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 97446a3a9ce637f766b03da297a2b9882472b0e1..7874908f369790519d73e029d0819a560c0fb714 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -24,7 +24,7 @@
         <mat-card-content>
 
             <!-- nom du module de calcul -->
-            <calc-name [title]="uitextCalculatorName"></calc-name>
+            <calc-name id="calculator-name" [title]="uitextCalculatorName"></calc-name>
 
             <div id="calc-cards-container" class="container" fxLayout="row wrap" fxLayoutAlign="space-around start">
                 <!-- chapitres -->
@@ -46,6 +46,7 @@
 
                 <!-- résultats -->
                 <mat-card id="calc-card-results" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
+                    <div id="fake-results-anchor"></div>
                     <mat-card-header>
                         <mat-card-title>
                             <h1 [innerHTML]="uitextResultsTitle"></h1>
diff --git a/src/app/components/generic-calculator/calculator.component.scss b/src/app/components/generic-calculator/calculator.component.scss
index b9275137bf8288272c846be0520777d73c5e211f..2346a487428bcb44594db9221dc7e84c2e6fd3ab 100644
--- a/src/app/components/generic-calculator/calculator.component.scss
+++ b/src/app/components/generic-calculator/calculator.component.scss
@@ -14,6 +14,12 @@
     margin-right: -1em;
 }
 
+// dirty fix for scrollIntoView() positioning
+#fake-results-anchor {
+    float: left; // to avoid following elements being affected by negative margin
+    margin-top: -54px;
+}
+
 mat-card {
     margin-bottom: 2em;
 
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index ffc2cf9d8fe41c3d9a92fa0beffdbfdd59f30eed..3496192aabb2636a334ae6753ef68c73ea743936 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -241,7 +241,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     }
 
     private scrollToResults() {
-        const element = document.getElementById("resultsComp");
+        const element = document.getElementById("fake-results-anchor");
         if (element) {
             element.scrollIntoView();
         }
diff --git a/src/app/components/log/log.component.scss b/src/app/components/log/log.component.scss
index 7dee1f9239623da8254eb25fedcaebd2acff4697..4c37d752b16c35c7d426ce82734044c40d02b32a 100644
--- a/src/app/components/log/log.component.scss
+++ b/src/app/components/log/log.component.scss
@@ -3,7 +3,7 @@
 }
 
 .hyd_log {
-    margin-top: 1em;
+    margin-top: 2.5em;
     border: solid #ccc 1px;
     border-radius: 2px;
     padding: 1em;
diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html
index 24c15f01effb82c4ca45e46839b49138fe3a8f09..4efd8c40dabe2d2ffd9fed7a21755f7e9c400fdb 100644
--- a/src/app/components/remous-results/remous-results.component.html
+++ b/src/app/components/remous-results/remous-results.component.html
@@ -1,16 +1,46 @@
-<div class="container" *ngIf="hasResults">
-    <div>
-        <chart [type]="graph1_type" [data]="graph1_data" [options]="graph1_options"></chart>
-    </div>
-    <div>
-        <chart *ngIf="extraGraph" [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart>
+<div class="remous-results-container" #remousResults *ngIf="hasResults" fxLayout="row wrap" fxLayoutAlign="center center">
+    <div fxFlex="1 1 100%">
+        <div class="remous-results-buttons">
+            <button mat-icon-button (click)="exportAsImage(remousResults)">
+                <mat-icon color="primary">image</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(remousResults)">
+                <mat-icon color="primary" class="scaled12">fullscreen</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()">
+                <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon>
+            </button>
+        </div>
+
+        <chart id="main-chart" ngClass.lt-sm="height300" ngClass.sm="height400" ngClass.md="height400" ngClass.gt-md="height600"
+            [type]="graph1_type" [data]="graph1_data" [options]="graph1_options">
+        </chart>
     </div>
+</div>
 
-    <!-- journal -->
-    <log></log>
+<div class="remous-results-extragraph-container" #remousResultsExtra *ngIf="extraGraph" fxLayout="row wrap" fxLayoutAlign="center center">
+    <div fxFlex="1 1 100%">
+        <div class="remous-results-buttons">
+            <button mat-icon-button (click)="exportAsImage(remousResultsExtra)">
+                <mat-icon color="primary">image</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(remousResultsExtra)">
+                <mat-icon color="primary" class="scaled12">fullscreen</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()">
+                <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon>
+            </button>
+        </div>
 
-    <div *ngIf="hasData">
-        <!-- résultats numériques -->
-        <var-results></var-results>
+        <chart [type]="graph2_type" [data]="graph2_data" [options]="graph2_options"></chart>
     </div>
 </div>
+
+
+<!-- journal -->
+<log></log>
+
+<div [hidden]="! hasData"><!-- *ngIf breaks @ViewChild availability-->
+    <!-- résultats numériques -->
+    <var-results></var-results>
+</div>
diff --git a/src/app/components/remous-results/remous-results.component.scss b/src/app/components/remous-results/remous-results.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a9966376574d9609f7e1cd5095fa03d80d0d9fa7
--- /dev/null
+++ b/src/app/components/remous-results/remous-results.component.scss
@@ -0,0 +1,39 @@
+.remous-results-container{
+    display: block;
+    background-color: white;
+}
+
+#main-chart {
+    &.height600 {
+        height:600px;
+    }
+    &.height400 {
+        height: 400px;
+    }
+    &.height300 {
+        height: 300px;
+    }
+}
+
+.remous-results-extragraph-container{
+    display: block;
+    background-color: white;
+}
+
+.remous-results-buttons {
+    padding-right: 10px;
+    padding-top: 4px;
+    text-align: right;
+    background-color: white;
+
+    button {
+        margin-left: 3px;
+        width: auto;
+
+        mat-icon {
+            &.scaled12 {
+                transform: scale(1.2);
+            }
+        }
+    }
+}
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index a64d46ce41d264b9370a6654be5d667281a374fc..d62a814e06bf032b3120d17d9a4058c5cb91096c 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -193,25 +193,8 @@ class GraphData {
 @Component({
     selector: "remous-results",
     templateUrl: "./remous-results.component.html",
-    styles: [`
-    .result_label {
-        text-align: right;
-        padding-top:10px;
-        padding-bottom:10px;
-        padding-right:10px;
-    }
-    .result_value {
-        text-align: center;
-        padding-left:30px;
-        padding-right:30px;
-    }
-    .result_id_0 {
-        background-color: #f0f0f0;
-    }
-    .result_id_2 {
-        font-weight: bold;
-    }
-    `
+    styleUrls: [
+        "./remous-results.component.scss"
     ]
 })
 export class RemousResultsComponent implements DoCheck {
@@ -253,6 +236,11 @@ export class RemousResultsComponent implements DoCheck {
     @ViewChild(LogComponent)
     private logComponent: LogComponent;
 
+    /** tracks the fullscreen state */
+    public get isFullscreen() {
+        return (document["fullscreenElement"] !== null);
+    }
+
     constructor(
         private intlService: I18nService,
         private appSetup: ApplicationSetupService
@@ -270,10 +258,6 @@ export class RemousResultsComponent implements DoCheck {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_ABSCISSE");
     }
 
-    private get uitextTirant() {
-        return this.intlService.localizeText("INFO_REMOUSRESULTS_TIRANT");
-    }
-
     private get uitextFond() {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_FOND");
     }
@@ -290,7 +274,7 @@ export class RemousResultsComponent implements DoCheck {
         return this.intlService.localizeText("INFO_REMOUSRESULTS_TIRANTCRITIQUE");
     }
 
-    private get extraGraph(): boolean {
+    public get extraGraph(): boolean {
         return this._remousResults === undefined ? false : this._remousResults.extraGraph;
     }
 
@@ -299,6 +283,23 @@ export class RemousResultsComponent implements DoCheck {
             this.intlService.getExtraResLabel(this._remousResults.extraParamSymbol);
     }
 
+    private headers(): string[] {
+        return this._tableHeaders;
+    }
+
+    private getResultClass(i: number) {
+        // tslint:disable-next-line:no-bitwise
+        return "result_id_" + String(i & 1);
+    }
+
+    public get hasResults(): boolean {
+        return this._remousResults !== undefined && this._remousResults.hasResults;
+    }
+
+    public get hasData(): boolean {
+        return this._remousResults && this._remousResults.result && this._remousResults.result.ok;
+    }
+
     public set results(rs: CalculatorResults[]) {
         this._remousResults = undefined;
         if (rs !== undefined) {
@@ -559,17 +560,12 @@ export class RemousResultsComponent implements DoCheck {
         const nDigits = this.appSetup.displayDigits;
         this.graph1_options = {
             responsive: true,
-            maintainAspectRatio: true,
+            maintainAspectRatio: false,
             animation: {
                 duration: 0
             },
             legend: {
                 display: true,
-                position: "right"
-            },
-            title: {
-                display: true,
-                text: this.uitextAbscisse,
                 position: "bottom"
             },
             scales: {
@@ -582,6 +578,10 @@ export class RemousResultsComponent implements DoCheck {
                         callback: function(value, index, values) {
                             return Number(value).toFixed(nDigits);
                         }
+                    },
+                    scaleLabel: {
+                        display: true,
+                        labelString: this.uitextAbscisse
                     }
                 }]
             },
@@ -605,31 +605,45 @@ export class RemousResultsComponent implements DoCheck {
                 },
                 legend: {
                     display: true,
-                    position: "right"
-                },
-                title: {
-                    display: true,
-                    text: this.uitextAbscisse,
                     position: "bottom"
+                },
+                scales: {
+                    xAxes: [{
+                        scaleLabel: {
+                            display: true,
+                            labelString: this.uitextAbscisse
+                        },
+                        ticks: {
+                            precision: nDigits,
+                            callback: function(value, index, values) {
+                                return Number(value).toFixed(nDigits);
+                            }
+                        },
+                    }]
+                },
+                tooltips: {
+                    callbacks: {
+                        label: function(tooltipItem, data) {
+                            return Number(tooltipItem.yLabel).toFixed(nDigits);
+                        }
+                    }
                 }
             };
         }
     }
 
-    private headers(): string[] {
-        return this._tableHeaders;
-    }
-
-    private getResultClass(i: number) {
-        // tslint:disable-next-line:no-bitwise
-        return "result_id_" + String(i & 1);
+    public setFullscreen(element) {
+        element.requestFullscreen();
     }
 
-    public get hasResults(): boolean {
-        return this._remousResults !== undefined && this._remousResults.hasResults;
+    public exitFullscreen() {
+        document.exitFullscreen();
     }
 
-    private get hasData(): boolean {
-        return this._remousResults && this._remousResults.result && this._remousResults.result.ok;
+    public exportAsImage(element: HTMLDivElement) {
+        const canvas: HTMLCanvasElement = element.querySelector("canvas");
+        canvas.toBlob((blob) => {
+            saveAs(blob, "chart.png");
+        }); // defaults to image/png
     }
 }
diff --git a/src/app/components/results-graph/results-graph.component.html b/src/app/components/results-graph/results-graph.component.html
index 9f0dc91e235577fd23ee2138e13f465f8b40409c..61ff43cc45dab0e93d125238794f82714cb90910 100644
--- a/src/app/components/results-graph/results-graph.component.html
+++ b/src/app/components/results-graph/results-graph.component.html
@@ -1,4 +1,20 @@
-<chart [type]="graph_type" [data]="graph_data" [options]="graph_options">
-</chart>
+<div class="graph-results-container" #graphResults fxLayout="row wrap" fxLayoutAlign="center center">
+    <div fxFlex="1 1 100%">
+        <div class="graph-results-buttons">
+            <button mat-icon-button (click)="exportAsImage(graphResults)">
+                <mat-icon color="primary">image</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(graphResults)">
+                <mat-icon color="primary" class="scaled12">fullscreen</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()">
+                <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon>
+            </button>
+        </div>
+
+        <chart [type]="graph_type" [data]="graph_data" [options]="graph_options" #graphChart>
+        </chart>
+    </div>
+</div>
 
 <graph-type></graph-type>
diff --git a/src/app/components/results-graph/results-graph.component.scss b/src/app/components/results-graph/results-graph.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..7a13a42ec3fbbf6f09d763c9cd79ea58173d65bf
--- /dev/null
+++ b/src/app/components/results-graph/results-graph.component.scss
@@ -0,0 +1,23 @@
+.graph-results-container{
+    display: block;
+    background-color: white;
+}
+
+.graph-results-buttons {
+    padding-right: 10px;
+    padding-top: 4px;
+    margin-bottom: -30px;
+    text-align: right;
+    background-color: white;
+
+    button {
+        margin-left: 3px;
+        width: auto;
+
+        mat-icon {
+            &.scaled12 {
+                transform: scale(1.2);
+            }
+        }
+    }
+}
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index 35dbf11cda534be7b9733acd4538dec58c29c931..0e0fbc26517117fb2b6d0c1fef79fdb4c24ba71b 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -8,7 +8,10 @@ import { ApplicationSetupService } from "../../services/app-setup/app-setup.serv
 
 @Component({
     selector: "results-graph",
-    templateUrl: "./results-graph.component.html"
+    templateUrl: "./results-graph.component.html",
+    styleUrls: [
+        "./results-graph.component.scss"
+    ]
 })
 export class ResultsGraphComponent implements AfterContentInit, Observer {
     private _results: VarResults;
@@ -36,6 +39,11 @@ export class ResultsGraphComponent implements AfterContentInit, Observer {
         }
     };
 
+    /** tracks the fullscreen state */
+    public get isFullscreen() {
+        return (document["fullscreenElement"] !== null);
+    }
+
     public constructor(
         private appSetup: ApplicationSetupService
     ) {
@@ -196,6 +204,21 @@ export class ResultsGraphComponent implements AfterContentInit, Observer {
         };
     }
 
+    public setFullscreen(element) {
+        element.requestFullscreen();
+    }
+
+    public exitFullscreen() {
+        document.exitFullscreen();
+    }
+
+    public exportAsImage(element: HTMLDivElement) {
+        const canvas: HTMLCanvasElement = element.querySelector("canvas");
+        canvas.toBlob((blob) => {
+            saveAs(blob, "chart.png");
+        }); // defaults to image/png
+    }
+
     // interface Observer
 
     update(sender: any, data: any) {
diff --git a/src/app/components/section-results/section-results.component.html b/src/app/components/section-results/section-results.component.html
index e9a103d4e780c34cea400353507f9b4762392762..2415b265547f4e7a83cd676108edaefd596f7b03 100644
--- a/src/app/components/section-results/section-results.component.html
+++ b/src/app/components/section-results/section-results.component.html
@@ -1,18 +1,20 @@
-<div class="container-fluid" *ngIf="hasResults">
-    <!-- graphique -->
-    <div class="row">
-        <div class="col" style="text-align: center">
-            <section-canvas></section-canvas>
+<div class="section-results-container" #sectionResults *ngIf="hasResults" fxLayout="row wrap" fxLayoutAlign="center center">
+    <div fxFlex="1 1 100%">
+        <div class="section-results-buttons">
+            <button mat-icon-button (click)="exportAsImage(sectionResults)">
+                <mat-icon color="primary">image</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="! isFullscreen" (click)="setFullscreen(sectionResults)">
+                <mat-icon color="primary" class="scaled12">fullscreen</mat-icon>
+            </button>
+            <button mat-icon-button *ngIf="isFullscreen" (click)="exitFullscreen()">
+                <mat-icon color="primary" class="scaled12">fullscreen_exit</mat-icon>
+            </button>
         </div>
-    </div>
 
-    <!-- tableau de valeurs -->
-    <div class="row">
-        <div class="col mx-auto">
-            <table style="width: 100%" cellpadding="15">
-                <tr vertical-result-element [result-element]=resultElement>
-                </tr>
-            </table>
+        <!-- graphique -->
+        <div class="canvas-container">
+            <section-canvas></section-canvas>
         </div>
     </div>
 </div>
diff --git a/src/app/components/section-results/section-results.component.scss b/src/app/components/section-results/section-results.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..15dd1020226e493cef9354441e3ce9cdbe22b480
--- /dev/null
+++ b/src/app/components/section-results/section-results.component.scss
@@ -0,0 +1,28 @@
+.section-results-container{
+    display: block;
+    background-color: white;
+}
+
+.section-results-buttons {
+    padding-right: 10px;
+    padding-top: 4px;
+    margin-bottom: -30px;
+    text-align: right;
+    background-color: white;
+
+    button {
+        margin-left: 3px;
+        width: auto;
+
+        mat-icon {
+            &.scaled12 {
+                transform: scale(1.2);
+            }
+        }
+    }
+}
+
+.canvas-container {
+    // border: dashed red 2px;
+    text-align: center;
+}
diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts
index 83ad69517fa2676d6d94324a98e2b4b52f89042f..34248eae2ec6dd6791f074dfb6a5397add5867df 100644
--- a/src/app/components/section-results/section-results.component.ts
+++ b/src/app/components/section-results/section-results.component.ts
@@ -6,55 +6,40 @@ import { SectionCanvasComponent } from "../section-canvas/section-canvas.compone
 import { SectionResults } from "../../results/section-results";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { CalculatorResults } from "../../results/calculator-results";
-import { I18nService } from "../../services/internationalisation/internationalisation.service";
+import { FixedResults } from "../../results/fixed-results";
 
 @Component({
     selector: "section-results",
     templateUrl: "./section-results.component.html",
-    styles: [`
-    .result_label {
-        text-align: right;
-        padding-top:10px;
-        padding-bottom:10px;
-        padding-right:10px;
-    }
-    .result_value {
-        text-align: center;
-        padding-left:30px;
-        padding-right:30px;
-    }
-    .result_id_0 {
-        background-color: #f0f0f0;
-    }
-    .result_id_2 {
-        font-weight: bold;
-    }
-    `]
+    styleUrls: [
+        "./section-results.component.scss"
+    ]
 })
 export class SectionResultsComponent implements DoCheck {
 
-    constructor(private appSetupService: ApplicationSetupService, private intlService: I18nService) { }
+    constructor(
+        private appSetupService: ApplicationSetupService
+    ) { }
 
     public set results(rs: CalculatorResults[]) {
         this._resultElement = undefined;
-
         this._results = undefined;
         if (rs) {
             for (const r of rs) {
                 if (r instanceof SectionResults) {
                     this._results = r;
-                    break;
                 }
             }
         }
         this.updateView();
     }
 
+    /** détermine s'il y a des résultats de section "fixes" (pas de paramètre varié, graphique de la section) */
     public get hasResults(): boolean {
         return this._results && this._results.hasResults;
     }
 
-    private get resultElement() {
+    public get resultElement() {
         return this._resultElement;
     }
 
@@ -67,9 +52,8 @@ export class SectionResultsComponent implements DoCheck {
         "Yc": { r: 255, g: 128, b: 0 },
         "Yco": { r: 255, g: 0, b: 255 },
     };
-    /**
-    * résultats non mis en forme
-    */
+
+    /**  résultats non mis en forme */
     private _results: SectionResults;
 
     /**
@@ -82,6 +66,11 @@ export class SectionResultsComponent implements DoCheck {
     @ViewChild(SectionCanvasComponent)
     private _sectionCanvas: SectionCanvasComponent;
 
+    /** tracks the fullscreen state */
+    public get isFullscreen() {
+        return (document["fullscreenElement"] !== null);
+    }
+
     public updateView() {
         if (this._sectionCanvas) {
             this._sectionCanvas.reset();
@@ -137,4 +126,19 @@ export class SectionResultsComponent implements DoCheck {
         // tslint:disable-next-line:no-bitwise
         return "result_id_" + String(i & 1);
     }
+
+    public setFullscreen(element) {
+        element.requestFullscreen();
+    }
+
+    public exitFullscreen() {
+        document.exitFullscreen();
+    }
+
+    public exportAsImage(element: HTMLDivElement) {
+        const canvas: HTMLCanvasElement = element.querySelector("canvas");
+        canvas.toBlob((blob) => {
+            saveAs(blob, "chart.png");
+        }); // defaults to image/png
+    }
 }
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index e5d22bcf919c95bb75d229c64fe0da09be0dd916..651ec045358362be6e6a3efbd4e21b7a2b5a1c13 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -1,16 +1,12 @@
-import { CalculatorType, acSection, ParamsEquation, ComputeNodeType, IObservable } from "jalhyd";
+import { IObservable } from "jalhyd";
 
 import { FormResultSection } from "../form-result-section";
 import { FormDefSection } from "../form-def-section";
-import { NgParameter } from "../../ngparam";
-import { InputField } from "../../input-field";
 import { FormComputeSectionParametree } from "../form-compute-section-parametree";
 import { FormulaireDefinition } from "../form-definition";
-import { I18nService } from "../../../services/internationalisation/internationalisation.service";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FieldSet } from "../../fieldset";
-import { SelectField } from "../../select-field";
 
 export class FormulaireSectionParametree extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index 5466762f0bad187cbcb20606afcf09461853ac23..ab2c327b54088ca42c14fb962d9590b6a6886923 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -1,4 +1,4 @@
-import { SectionParametree, acSection } from "jalhyd";
+import { SectionParametree, acSection, Result } from "jalhyd";
 
 import { FormCompute } from "./form-compute";
 import { NgParameter } from "../ngparam";
@@ -80,9 +80,16 @@ export class FormComputeSectionParametree extends FormCompute {
         this._sectionResults.section = sect;
 
         const computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
-        this._sectionResults.result = sectNub.CalcSerie(computePrec,
+        const tmpResult: Result = sectNub.CalcSerie(computePrec,
             undefined, // valeur initiale, non utilisée dans ce cas
             undefined // variable à calculer, non utilisée
         );
+
+        // résultats de section (avec le graphique de section)
+        this._sectionResults.result = tmpResult;
+
+        // résultats complémentaires des paramètres fixés
+        this._formSectionResult.addSectionFixedParameters(false);
+        this._formSectionResult.fixedResults.result = tmpResult;
     }
 }
diff --git a/src/app/results/section-results.ts b/src/app/results/section-results.ts
index ee05b29435cdac3b9d928d6dd58a4770f52a3fa3..c2ab16e7f3650263f18a95015d8327f878adbecc 100644
--- a/src/app/results/section-results.ts
+++ b/src/app/results/section-results.ts
@@ -1,7 +1,6 @@
-import { acSection, Result, ResultElement } from "jalhyd";
+import { acSection, Result } from "jalhyd";
 
 import { CalculatorResults } from "./calculator-results";
-import { NgParameter } from "../formulaire/ngparam";
 
 export class SectionResults extends CalculatorResults {
     private _result: Result;
diff --git a/src/assets/icons/file-excel-box.svg b/src/assets/icons/file-excel-box.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f0be5069bf8d7c2cf0b39456b0c5ee8dccb5c525
--- /dev/null
+++ b/src/assets/icons/file-excel-box.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.2,17H14.2L12,13.2L9.8,17H7.8L11,12L7.8,7H9.8L12,10.8L14.2,7H16.2L13,12M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z" /></svg>
\ No newline at end of file
diff --git a/src/assets/icons/file-excel.svg b/src/assets/icons/file-excel.svg
new file mode 100644
index 0000000000000000000000000000000000000000..77acecd831d1b6a18f1b6c8c8d2f7b473b3a6106
--- /dev/null
+++ b/src/assets/icons/file-excel.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M6,2H14L20,8V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M13,3.5V9H18.5L13,3.5M17,11H13V13H14L12,14.67L10,13H11V11H7V13H8L11,15.5L8,18H7V20H11V18H10L12,16.33L14,18H13V20H17V18H16L13,15.5L16,13H17V11Z" /></svg>
\ No newline at end of file