Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSV export feature for easy reporting #237

Open
eldho-varghese opened this issue Sep 5, 2021 · 2 comments
Open

CSV export feature for easy reporting #237

eldho-varghese opened this issue Sep 5, 2021 · 2 comments

Comments

@eldho-varghese
Copy link

Hi @fboender

It would be nice to have a csv export button in fancy_html_split template based on the columns enabled. This will helps to generate various reports quickly.

At present, I'm enabling required columns fancy_html_split page and select all the columns (Ctrl +A) and just paste that onto excel or CSV sheet and that works nicely.

Thanks
Eldho Varghese

@fboender
Copy link
Owner

fboender commented Sep 5, 2021

Hey eldho-varghese!

Agreed that this would be nice. It's technically possible to implement this I think, but it's a fair amount of work. Would a browser plugin be a good alternative? There are various plugins available that let you export HTML tables to CSV or Excel in the browser directly. Nice addition is that this works for all tables, not just ansible-cmdb.

I found these:

Let me know if that's a workable alternative. If not I'll look into implementing this in the future, but to be honest it'll probably be low priority for now.

@adpavlov
Copy link

below code can be added to html template in <header> section to have Download CSV button and function:

    <span id="clear_settings"><a href="javascript:downloadCSV();">Download CSV</a></span>
    <script>
    function downloadCSV() {
      // Get table data as array
      const table = document.getElementById("host_overview_tbl");
      const rows = table.getElementsByTagName("tr");
      const data = [];
      for (let i = 0; i < rows.length; i++) {
        const row = rows[i];
        const cols = row.getElementsByTagName("td");
        // Skip empty rows
        if (cols.length === 0) {
          continue;
        }
        const rowData = [];
        for (let j = 0; j < cols.length; j++) {
          rowData.push(cols[j].innerText);
        }
        data.push(rowData);
      }

      // Add headers to data array
      const headers = Array.from(table.getElementsByTagName("th")).map(th => th.innerText);
      data.unshift(headers);

      // Convert array to CSV string
      let csv = "";
      for (let i = 0; i < data.length; i++) {
        const row = data[i];
        for (let j = 0; j < row.length; j++) {
          const val = row[j].replace(/"/g, '""');
          if (val.indexOf(",") > -1 || val.indexOf("\n") > -1) {
            csv += `"${val}"`;
          } else {
            csv += val;
          }
          if (j < row.length - 1) {
            csv += ",";
          }
        }
        csv += "\n";
      }

      // Download CSV file
      const filename = "file.csv";
      const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
      if (navigator.msSaveBlob) {
        navigator.msSaveBlob(blob, filename);
      } else {
        const link = document.createElement("a");
        if (link.download !== undefined) {
          // feature detection
          const url = URL.createObjectURL(blob);
          link.setAttribute("href", url);
          link.setAttribute("download", filename);
          link.style.visibility = "hidden";
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
      }
    }
    </script>

However, some other job needs to be done as ansible-cmdb fails in such case with parsing:

Whoops, it looks like something went wrong while rendering the template.

The reported error was: NameError: Undefined

The full error was:
    
    Traceback (most recent call last):
      File "/home/devops/.local/bin/../lib/ansiblecmdb/ansible-cmdb.py", line 214, in <module>
        output = renderer.render(ansible.get_hosts(), params)
      File "/home/devops/.local/lib/python3.9/site-packages/ansiblecmdb/render.py", line 42, in render
        return self._render_mako(hosts, vars)
      File "/home/devops/.local/lib/python3.9/site-packages/ansiblecmdb/render.py", line 59, in _render_mako
        return template.render(hosts=hosts, **vars)
      File "/home/devops/.local/lib/python3.9/site-packages/mako/template.py", line 439, in render
        return runtime._render(self, self.callable_, args, data)
      File "/home/devops/.local/lib/python3.9/site-packages/mako/runtime.py", line 874, in _render
        _render_context(
      File "/home/devops/.local/lib/python3.9/site-packages/mako/runtime.py", line 916, in _render_context
        _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
      File "/home/devops/.local/lib/python3.9/site-packages/mako/runtime.py", line 943, in _exec_template
        callable_(context, *args, **kwargs)
      File "/home/devops/dna-aws/dna-aws/inventory_dashboard/all/all_all_html_fancy.tpl", line 33, in render_body
        <% html_header_bar("all") %>
      File "all_all_html_fancy_defs.html", line 270, in render_html_header_bar
        csv += `"${val}"`;
      File "/home/devops/.local/lib/python3.9/site-packages/mako/filters.py", line 47, in decode
        return decode(str(x))
      File "/home/devops/.local/lib/python3.9/site-packages/mako/runtime.py", line 230, in __str__
        raise NameError("Undefined")
    NameError: Undefined

So I'm adding this code after generation with ansible-cmdb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants