diff --git a/routes/reports.js b/routes/reports.js
index 06ac886..7af069e 100644
--- a/routes/reports.js
+++ b/routes/reports.js
@@ -2,6 +2,44 @@ const Boom = require("boom");
 const json2csv = require("json2csv");
 
 const bookshelf = require("../db/bookshelf_init");
+const supportedOutputs = ["csv", "json"];
+
+const initTotalObj = sourceObj => {
+  let targetObj = {};
+  for (let property in sourceObj) {
+    targetObj[property] = 0;
+  }
+  return targetObj;
+};
+
+const sumUpResults = (...objs) => {
+  return objs.reduce((a, b) => {
+    for (let k in b) {
+      if (b.hasOwnProperty(k)) {
+        if (typeof b[k] === "number") {
+          a[k] = (a[k] || 0) + b[k];
+        } else a[k] = null;
+      }
+    }
+    return a;
+  }, {});
+};
+
+const parseResults = row => {
+  row = {
+    ...row,
+    road_count_add: parseInt(row.road_count_add, 10),
+    road_count_mod: parseInt(row.road_count_mod, 10),
+    building_count_add: parseInt(row.building_count_add, 10),
+    building_count_mod: parseInt(row.building_count_mod, 10),
+    waterway_count_add: parseInt(row.waterway_count_add, 10),
+    poi_count_add: parseInt(row.poi_count_add, 10),
+    road_km_add: Number(Number(row.road_km_add).toFixed(2)),
+    road_km_mod: Number(Number(row.road_km_mod).toFixed(2)),
+    waterway_km_add: Number(Number(row.waterway_km_add).toFixed(2))
+  };
+  return row;
+};
 
 module.exports = [
   {
@@ -16,6 +54,7 @@ module.exports = [
 
       let startDate = new Date(0);
       let endDate = new Date();
+      let outputType = "";
 
       if (req.query.startdate != null) {
         startDate = new Date(req.query.startdate);
@@ -25,6 +64,18 @@ module.exports = [
         endDate = new Date(req.query.enddate);
       }
 
+      try {
+        if (req.query.output != null) {
+          if (supportedOutputs.includes(req.query.output)) {
+            outputType = req.query.output;
+          } else throw new Error();
+        } else {
+          outputType = "csv";
+        }
+      } catch (err) {
+        return res(Boom.notFound("Specified Output Format is not supported"));
+      }
+
       const wildcards = hashtags
         .filter(x => x.match(/\*$/))
         .map(x => x.replace(/\*/, "%"));
@@ -65,21 +116,17 @@ module.exports = [
           .whereBetween("created_at", [startDate, endDate])
           .groupBy("filtered.hashtag");
 
-        const data = results.map(row => ({
-          ...row,
-          road_count_add: parseInt(row.road_count_add, 10),
-          road_count_mod: parseInt(row.road_count_mod, 10),
-          building_count_add: parseInt(row.building_count_add, 10),
-          building_count_mod: parseInt(row.building_count_mod, 10),
-          waterway_count_add: parseInt(row.waterway_count_add, 10),
-          poi_count_add: parseInt(row.poi_count_add, 10),
-          road_km_add: Number(Number(row.road_km_add).toFixed(2)),
-          road_km_mod: Number(Number(row.road_km_mod).toFixed(2)),
-          waterway_km_add: Number(Number(row.waterway_km_add).toFixed(2))
-        }));
+        let hashtagTotal = initTotalObj(results[0]);
+        let data = results.map(function(row) {
+          let parsedRow = parseResults(row);
+          hashtagTotal = sumUpResults(hashtagTotal, parsedRow);
+          return parsedRow;
+        });
+        hashtagTotal.hashtag = "TOTAL";
+        data.push(hashtagTotal);
 
-        return res(
-          json2csv({
+        if (outputType === "csv") {
+          data = json2csv({
             data,
             fields: [
               {
@@ -123,10 +170,14 @@ module.exports = [
                 value: "poi_count_add"
               }
             ]
-          })
-        )
-          .type("text/csv")
-          .header("Content-Disposition", "attachment; filename=hashtags.csv");
+          });
+        }
+        return res(data)
+          .type("text/" + outputType)
+          .header(
+            "Content-Disposition",
+            "attachment; filename=hashtags." + outputType
+          );
       } catch (err) {
         return res(err);
       }
@@ -146,6 +197,7 @@ module.exports = [
 
       let startDate = new Date(0);
       let endDate = new Date();
+      let outputType = "";
 
       if (req.query.startdate != null) {
         startDate = new Date(req.query.startdate);
@@ -155,6 +207,18 @@ module.exports = [
         endDate = new Date(req.query.enddate);
       }
 
+      try {
+        if (req.query.output != null) {
+          if (supportedOutputs.includes(req.query.output)) {
+            outputType = req.query.output;
+          } else throw new Error();
+        } else {
+          outputType = "csv";
+        }
+      } catch (err) {
+        return res(Boom.notFound("Specified Output Format is not supported"));
+      }
+
       try {
         const results = await knex
           .sum("road_count_add AS road_count_add")
@@ -174,21 +238,17 @@ module.exports = [
           .whereBetween("changesets.created_at", [startDate, endDate])
           .groupBy("name");
 
-        const data = results.map(row => ({
-          ...row,
-          road_count_add: parseInt(row.road_count_add, 10),
-          road_count_mod: parseInt(row.road_count_mod, 10),
-          building_count_add: parseInt(row.building_count_add, 10),
-          building_count_mod: parseInt(row.building_count_mod, 10),
-          waterway_count_add: parseInt(row.waterway_count_add, 10),
-          poi_count_add: parseInt(row.poi_count_add, 10),
-          road_km_add: Number(Number(row.road_km_add).toFixed(2)),
-          road_km_mod: Number(Number(row.road_km_mod).toFixed(2)),
-          waterway_km_add: Number(Number(row.waterway_km_add).toFixed(2))
-        }));
+        let userTotal = initTotalObj(results[0]);
+        let data = results.map(function(row) {
+          let parsedRow = parseResults(row);
+          userTotal = sumUpResults(userTotal, parsedRow);
+          return parsedRow;
+        });
+        userTotal.name = "TOTAL";
+        data.push(userTotal);
 
-        return res(
-          json2csv({
+        if (outputType === "csv") {
+          data = json2csv({
             data,
             fields: [
               {
@@ -232,10 +292,15 @@ module.exports = [
                 value: "poi_count_add"
               }
             ]
-          })
-        )
-          .type("text/csv")
-          .header("Content-Disposition", "attachment; filename=users.csv");
+          });
+        }
+
+        return res(data)
+          .type("text/" + outputType)
+          .header(
+            "Content-Disposition",
+            "attachment; filename=users." + outputType
+          );
       } catch (err) {
         return res(err);
       }