Lowdefy
How to generate CSVs using Lowdefy

How to generate CSVs using Lowdefy

Adding the functionality to generate a CSV file in Lowdefy can be accomplished by using a JsAction. This action can be triggered by any in app event, such as clicking a button. This action evokes a JavaScript function that generates and downloads a CSV file.

Click the button below to see this in action:

The full project folder for this how-to is available at: https://github.com/lowdefy/lowdefy/tree/main/packages/docs/howto/generateCsv

This how-to assumes that you are already running a Lowdefy app locally in dev mode. If not:

  1. Create a empty folder.
  2. Open your terminal or cmd and cd to your empty folder.
  3. Run npx lowdefy@latest init && npx lowdefy@latest dev to initialize and start your Lowdefy app development server.

Generate CSV files TLDR;

  1. Add the CSV JavaScript function to the app and register the JsAction method.
  2. Load the custom JavaScript using a script tag.
  3. Add a JsAction to a button's onClick event with parameters populated.

1. Add the CSV JavaScript function to the app and register the JsAction method

Custom JavaScript code can be added to a Lowdefy app to allow it to accomplish things that extend the functionality of Lowdefy. Let's create a custom action which will generate a CSV based on a JavaScript function called csvMakeFn.

  1. Create a public folder inside your Lowdefy working directory.
  2. Since all content in the public folder is served by the Lowdefy server, simply create a csvMake.js file inside the public folder.
  3. Add this script to the file and save.
/public/csvMake.js
const csvMakeFn = async (
  context,
  filename,
  data,
  fields,
  ) => {
  if (!Array.isArray(data) || typeof data[0] !== 'object') {
    throw new Error('csvMake data takes an array of objects');
  }
  if (!fields) {
    fields = Object.keys(data[0]);
  }
  const arrays = [fields];
  data.forEach(obj => arrays.push(fields.map(field => obj[field])));
  const csv = arrays.map(row =>
    row
    .map(cell => typeof cell === 'undefined' || cell === null ? '' : cell)
    .map(String)
    .map(v => v.replaceAll('"', '""'))
    .map(v => `"${v}"`)
    .join(',')
  ).join('\r\n');
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const el = document.createElement('a');
  el.href = url;
  el.setAttribute('download', filename);
  el.click();
};
window.lowdefy.registerJsAction('csvMake', csvMakeFn);

This script gets a few things done, firstly a csvMake function is defined and it checks if an array of data has been provided and whether the CSV fields have been populated. It then creates an array with fields and adds the provided data to the array according to the field definition. Finally, a file is downloaded using this data string.

It is important to note that to call this function from within your Lowdefy app, it needs to be registered as a JsAction. This is done by calling the window.registerAction function, which takes two arguments - the action name and the action function. Once this is done, the action can be triggered by any event that calls this function along with parameters.

2. Load the custom JavaScript using a script tag

To load the external JavaScript file we use the app.html.appendHead property in the lowdefy.yaml file to add a script tag that loads the module:

/lowdefy.yaml
name: Generate a CSV
lowdefy: v3.23.3
app:
  html:
    appendHead: |
      <script type="module" src="/public/csvMake.js"></script>
pages:
# ...

This instructs the browser to fetch and execute our JavaScript file, which registers the action function so it can be used in the app.

3. Add a JsAction to a button's onClick event with parameters populated

Lowdefy actions are triggered by events, like onClick when a user clicks a button, or onEnter when the page loads. Lowdefy comes with a list of predefined actions, however, sometimes custom code is just what you need.

By default Lowdefy builds apps with a set of pre-configured, default block types to make it easier to build apps, for example using Button, TextInput, Box, etc. All the blocks documented in the Lowdefy docs are default types.

We will be using a Button with an onClick event to trigger the JsAction that will generate and download the CSV from the provided data.

We will need to pass an array with the arguments for the csvMake function (csv filename, data, field definitions) to the custom JsAction.

Edit the docs_button in the Welcome page to include the JsAction as shown below:

/lowdefy.yaml
lowdefy: 3.23.3
name: Generate PDF from data with Lowdefy

app:
  html:
    appendHead: |
      <script type="module" src="/public/csvMake.js"></script>

pages:
  - id: example
    type: PageHeaderMenu
    properties:
      title: Example
    areas:
      content:
        justify: center
        blocks:
          - id: generate_csv
            type: Button
            properties:
              size: large
              title: Generate a CSV
              color: '#1890ff'
            events:
              onClick:
                - id: generate_csv
                  type: JsAction
                  params:
                    name: csvMake
                    args:
                      - profiles.csv          # csv filename
                      - - Username: booker12  # an array of data, usually a reference
                          Identifier: 9012
                          FirstName: Rachel
                          LastName: Booker
                        - Username: grey07
                          Identifier: 2070
                          FirstName: Laura
                          LastName: Grey
                        - Username: johnson81
                          Identifier: 4081
                          FirstName: Craig
                          LastName: Johnson
                        - Username: jenkins46
                          Identifier: 9346
                          FirstName: Mary
                          LastName: Jenkins
                        - Username: smith79
                          Identifier: 5079
                          FirstName: Jamie
                          LastName: Smith
                      - - Username           # an array of field definitions
                        - Identifier
                        - FirstName
                        - LastName

Conclusion

Congratulations 🏆 your custom JsAction is now available in your Lowdefy app and ready to use to generate a CSV with the click of a button.

Check out the project folder for this how-to and why not give it a try: https://github.com/lowdefy/lowdefy/tree/main/packages/docs/howto/generateCsv

Next, try fetching data from a data source and generate a CSV from the returned data.


Comments and questions regarding this how-to are availible on this GitHub Discussions Thread
This how-to article was written by: