Найти тему
Nuances of programming

Как создать трекер расходов с SheetJS

Оглавление

Источник: Nuances of Programming

Знакомство с SheetJS

Представьте, что вы работаете бухгалтером в крупном супермаркете. По роду своей деятельности вы создаете электронные таблицы, чтобы отслеживать финансовые операции магазина и обрабатывать большие объемы числовых данных. В ваши обязанности входит:

  • открыть редактор электронных таблиц и внести список продаж за каждый день;
  • построить график и подсчитать общую прибыль и объем продаж;
  • применить формулы к данным для аналитических целей;
  • и наконец, отправить составленный документ руководителю отдела или другим инстанциям.

Все действия вполне осуществимы. А что если за один день происходят сотни продаж? Тогда вы потратите много сил и времени, поскольку будете снова и снова делать одно и то же. Это проблема, и ее надо как-то решать.

Попробуем автоматизировать описанный процесс с помощью API. Для этой цели воспользуемся библиотекой SheetJS, которая позволяет разработчикам управлять документами Excel посредством JavaScript.

В данной статье на основе терминала мы создадим трекер расходов, который будет добавлять их в файл Excel и подсчитывать общую сумму. Итогом работы станет следующий результат:

-2

Цель ясна, приступаем к ее реализации!

Начальный этап

Инициализируем репозиторий проекта с помощью указанной команды терминала:

mkdir sheet-tutorial #создаем каталог проекта
cd sheet-tutorial
npm init -y #инициализируем проект
Installation of modules

Установка модулей

В проекте задействованы модули:

  • yargs  —  для проектирования интерфейса терминала;
  • xlsx  —  для взаимодействия с электронными таблицами посредством кода.

Устанавливаем эти зависимости, выполняя данную bash-инструкцию:

npm i yargs xlsx

Создание проекта

Написание временных данных

В этом разделе создадим файл Excel, который послужит базой данных для приложения.

Переходим в корневой каталог проекта, где создаем файл Expenses.xlsx. В нем будут храниться данные о расходах клиента.

В Expenses.xlsx вводим следующие данные:

В таблице два заголовка: Category (категория) и Amount (количество)!
В таблице два заголовка: Category (категория) и Amount (количество)!

Как видно, мы создали два заголовка, а именно Category и Amount, и указали под ними различные пункты расходов и соответствующие им суммы.

Написание вспомогательных функций

В проекте создаем файл sheetUtils.js. В этот модуль войдут вспомогательные методы для управления базой данных.

В sheetUtils.js сначала прописываем данный код:

const xlsx = require("xlsx");
const path = require("path");

const fileLocation = path.join(__dirname, "Expenses.xlsx");

const fileContents = xlsx.readFile(fileLocation);
const firstSheet = fileContents.SheetNames[0];
const sheetValues = fileContents.Sheets[firstSheet];
const parsedJSON = xlsx.utils.sheet_to_json(sheetValues);

function getParsedJSON() {
return parsedJSON;
}

console.log(getParsedJSON());

  • Строка 4. С помощью модуля path создаем путь к документу Expenses.xlsx.
  • Строки 6–8. Читаем содержимое документа и сохраняем его значение в переменной sheetValues.
  • Строка 9. Преобразуем сохраненные данные в sheetValues в формат JSON, что позволяет легко выполнять арифметические операции.
  • Строка 15. Выводим значение метода getParsedJSON для целей отладки.

Проверяем, что получилось! Запускаем программу командой:

node sheetUtils

Результат:

-4

Как видно, SheetJS вернула массив ранее введенных записей. Кроме того, обратите внимание, что заголовки Category и Amount теперь используются как ключи в объектах JSON.

Далее пишем код, позволяющий пользователю добавлять расходы в электронную таблицу.

Для этого дополняем файл sheetUtils.js указанным кодом:

function addEntry(text) {
xlsx.utils.sheet_add_aoa(sheetValues, [text], { origin: -1 }); //свойство 'origin' указывает Node добавить запись в следующую доступную строку
xlsx.writeFile(fileContents, fileLocation);
}
addEntry(["Cake for girlfriend's birthday", 30]);

  • Строка 2. Вспомогательный метод вставляет значение text в виде новой записи на рабочем листе.
  • Строка 3. Сохраняем измененный документ Expenses.xlsx.
  • Строка 5. Выполняем метод addEntry для внесения нового пункта расходов в файл.

Получаем вот такой результат в таблице:

-5

Как видно, SheetJS добавила выбранные данные в электронную таблицу. Это значит, что программа в полном порядке!

Осталось лишь создать функцию, которая будет отображать общую сумму расходов. Для этого добавляем фрагмент кода в sheetUtils.js :

function getTotal() {
const allData = getParsedJSON();
const totalResult = allData
.map((item) => item.Amount)
.reduce((acc, a) => acc + a, 0);
return totalResult;
}
console.log("Current total ", getTotal());
module.exports = { getParsedJSON, addEntry, getTotal };

  • Строка 2. Получаем содержимое электронной таблицы в формате JSON.
  • Строки 3–5. С помощью функции map и reduce извлекаем значения Amount из массива JSON и суммируем их. Сохраняем результат сложения в переменной totalResult.
  • Строка 8. Выводим итоговую сумму в консоль.
  • Строка 9. Экспортируем пользовательские функции для применения в проекте.

Ниже представлен результат кода:

-6

Программа отлично работает!

Окончательный вариант файла sheetUtils.js выглядит так:

const xlsx = require("xlsx");
const path = require("path");

const fileLocation = path.join(__dirname, "Expenses.xlsx");

const fileContents = xlsx.readFile(fileLocation);
const firstSheet = fileContents.SheetNames[0];
const sheetValues = fileContents.Sheets[firstSheet];
const parsedJSON = xlsx.utils.sheet_to_json(sheetValues);

function getParsedJSON() {
return parsedJSON;
}

function addEntry(text) {
xlsx.utils.sheet_add_aoa(sheetValues, [text], { origin: -1 });
xlsx.writeFile(fileContents, fileLocation);
}

function getTotal() {
const allData = getParsedJSON();
const totalResult = allData
.map((item) => item.Amount)
.reduce((acc, a) => acc + a, 0);
return totalResult;
}

module.exports = { getParsedJSON, addEntry, getTotal };

Создание CLI

После создания вспомогательных методов переходим к проектированию интерфейса командной строки, тем самым обеспечивая пользователю взаимодействие с программой.

Сначала создаем файл index.js, в котором прописываем код:

const yargs = require("yargs/yargs");
const { addEntry, getTotal, getParsedJSON } = require("./sheetUtils");

const argv = yargs(process.argv.slice(2))
.alias("a", "add-amount")
.describe("a", "Add new expense to the table")
.alias("-c", "-category")
.describe("c", "Type of expense")
.command("overview", "Get list of expenses:", () => {
console.log(getParsedJSON());
})
.command("total", "Get total amount", () => {
console.log("Your total is: " + getTotal());
}).argv;
console.log(argv);

  • Строки 4–8. Используем модуль yargs для определения опций add-amount и category. Они позволяют пользователю добавлять новые записи в базу данных.
  • Строки 9 и 10. Даем описание команды overview. При ее выполнении программа реализует метод getParsedJSON.
  • Строки 12 и 13. Определяем команду total, при выполнении которой приложение отображает общую сумму расходов пользователя.

Время тестировать! Запускаем программу:

node index --help

Получаем результат:

-7

Теперь необходимо написать дополнительный код для поддержки опций category и add-amount. С этой целью добавляем данные строки в index.js:

//file: index.js
if (argv.a && argv.c) {
addEntry([argv.c, argv.a]);
console.log("Added expense: ", argv.c, argv.a);
}

  • Строка 3. Выполняем метод addEntry и передаем входные данные пользователя в качестве параметров функции.
  • Строка 4. Сообщаем пользователю о добавлении записей в файл.

Результат:

-8

Посмотрим, что происходит в файле Expenses.xlsx:

-9

Обратите внимание, что последняя запись успешно добавлена в файл. Это значит, что программа прекрасно работает.

Цель достигнута!

Заключение

Теперь вы знаете, как создать простой трекер расходов с помощью SheetJS. Используя эту удобную библиотеку, вы можете без особого труда работать с электронными таблицами.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Hussain Arif: Build an Expense Tracker with SheetJS