import
android.Manifest;
import
android.app.ProgressDialog;
import
android.content.Intent;
import
android.content.pm.PackageManager;
import
android.net.Uri;
import
android.os.AsyncTask;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.Button;
import
android.widget.Toast;
import
androidx.annotation.NonNull;
import
androidx.annotation.Nullable;
import
androidx.appcompat.app.AppCompatActivity;
import
androidx.core.app.ActivityCompat;
import
com.google.android.gms.tasks.OnCompleteListener;
import
com.google.android.gms.tasks.Task;
import
com.google.firebase.database.FirebaseDatabase;
import
org.apache.poi.ss.usermodel.Cell;
import
org.apache.poi.ss.usermodel.FormulaEvaluator;
import
org.apache.poi.ss.usermodel.Row;
import
org.apache.poi.xssf.usermodel.XSSFSheet;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook;
import
java.io.FileNotFoundException;
import
java.io.IOException;
import
java.io.InputStream;
import
java.util.HashMap;
import
java.util.UUID;
public
class
MainActivity
extends
AppCompatActivity {
public
static
final
int
cellCount =
2
;
Button excel;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
excel = findViewById(R.id.excel);
excel.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
if
(ActivityCompat.checkSelfPermission(MainActivity.
this
, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
selectfile();
}
else
{
ActivityCompat.requestPermissions(MainActivity.
this
,
new
String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
101
);
}
}
});
}
@Override
public
void
onRequestPermissionsResult(
int
requestCode,
@NonNull
String[] permissions,
@NonNull
int
[] grantResults) {
super
.onRequestPermissionsResult(requestCode, permissions, grantResults);
if
(requestCode ==
101
) {
if
(grantResults[
0
] == PackageManager.PERMISSION_GRANTED) {
selectfile();
}
else
{
Toast.makeText(MainActivity.
this
,
"Permission Not granted"
, Toast.LENGTH_LONG).show();
}
}
}
private
void
selectfile() {
Intent intent =
new
Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType(
"*/*"
);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent,
"Select File"
),
102
);
}
protected
void
onActivityResult(
int
requestCode,
int
resultCode,
@Nullable
Intent data) {
super
.onActivityResult(requestCode, resultCode, data);
if
(requestCode ==
102
) {
if
(resultCode == RESULT_OK) {
String filepath = data.getData().getPath();
if
(filepath.endsWith(
".xlsx"
) || filepath.endsWith(
".xls"
)) {
readfile(data.getData());
}
else
{
Toast.makeText(
this
,
"Please Select an Excel file to upload"
, Toast.LENGTH_LONG).show();
}
}
}
}
ProgressDialog dialog;
private
void
readfile(
final
Uri file) {
dialog =
new
ProgressDialog(
this
);
dialog.setMessage(
"Uploading"
);
dialog.setCanceledOnTouchOutside(
false
);
dialog.show();
AsyncTask.execute(
new
Runnable() {
@Override
public
void
run() {
final
HashMap<String, Object> parentmap =
new
HashMap<>();
try
{
XSSFWorkbook workbook;
try
(InputStream inputStream = getContentResolver().openInputStream(file)) {
workbook =
new
XSSFWorkbook(inputStream);
}
final
String timestamp =
""
+ System.currentTimeMillis();
XSSFSheet sheet = workbook.getSheetAt(
0
);
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
int
rowscount = sheet.getPhysicalNumberOfRows();
if
(rowscount >
0
) {
for
(
int
r =
0
; r < rowscount; r++) {
Row row = sheet.getRow(r);
if
(row.getPhysicalNumberOfCells() == cellCount) {
String A = getCellData(row,
0
, formulaEvaluator);
String B = getCellData(row,
1
, formulaEvaluator);
HashMap<String, Object> quetionmap =
new
HashMap<>();
quetionmap.put(
"A"
, A);
quetionmap.put(
"B"
, B);
String id = UUID.randomUUID().toString();
parentmap.put(id, quetionmap);
}
else
{
dialog.dismiss();
Toast.makeText(MainActivity.
this
,
"row no. "
+ (r +
1
) +
" has incorrect data"
, Toast.LENGTH_LONG).show();
return
;
}
}
runOnUiThread(
new
Runnable() {
@Override
public
void
run() {
FirebaseDatabase.getInstance().getReference().child(
"Data"
).
child(timestamp).updateChildren(parentmap).addOnCompleteListener(
new
OnCompleteListener<Void>() {
@Override
public
void
onComplete(
@NonNull
Task<Void> task) {
if
(task.isSuccessful()) {
dialog.dismiss();
Toast.makeText(MainActivity.
this
,
"Uploaded Successfully"
, Toast.LENGTH_LONG).show();
}
else
{
dialog.dismiss();
Toast.makeText(MainActivity.
this
,
"Something went wrong"
, Toast.LENGTH_LONG).show();
}
}
});
}
});
}
else
{
runOnUiThread(
new
Runnable() {
@Override
public
void
run() {
dialog.dismiss();
Toast.makeText(MainActivity.
this
,
"File is empty"
, Toast.LENGTH_LONG).show();
}
});
return
;
}
}
catch
(
final
FileNotFoundException e) {
e.printStackTrace();
runOnUiThread(
new
Runnable() {
@Override
public
void
run() {
Toast.makeText(MainActivity.
this
, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
catch
(
final
IOException e) {
e.printStackTrace();
runOnUiThread(
new
Runnable() {
@Override
public
void
run() {
Toast.makeText(MainActivity.
this
, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
});
}
private
String getCellData(Row row,
int
cellposition, FormulaEvaluator formulaEvaluator) {
String value =
""
;
Cell cell = row.getCell(cellposition);
switch
(cell.getCellType()) {
case
Cell.CELL_TYPE_BOOLEAN:
return
value + cell.getBooleanCellValue();
case
Cell.CELL_TYPE_NUMERIC:
return
value + cell.getNumericCellValue();
case
Cell.CELL_TYPE_STRING:
return
value + cell.getStringCellValue();
default
:
return
value;
}
}
}
Многие любят Excel и пользуются им для решения повседневных задач. Это удобно на большом экране, с клавиатурой и мышкой, но с телефона или планшета вводить информацию сложно. Если вы находитесь вне офиса, без компьютера под рукой, работа с электронными таблицами может стать сущим адом.
Хороший способ сохранить сильные стороны Excel и обойти слабые – создание собственного приложения, которое может обрабатывать данные из ваших таблиц на любом устройстве: компьютере, планшете или смартфоне. О том, как сделать это самостоятельно, без помощи программистов, я расскажу в статье.
Что такое AppSheet
Платформа AppSheet – одно из популярных средств разработки приложений так называемого низкого кода (LCDP). В отличие от традиционного программирования, где все делается в текстовом редакторе, на языках вроде C++, Python или Java, тут используется специальный графический интерфейс.
В AppSheet приложения собираются как из кубиков – просто и интуитивно понятно. А главное, для этого не требуется каких-то специальных знаний. С помощью платформы можно самостоятельно делать мобильные, планшетные и веб-приложения, используя электронные таблицы и базы данных из Google Drive, DropBox, Office 365 или откуда-то еще.
Приложения AppSheet упрощают ввод и обработку данных на любых платформах, в них можно использовать бесконтактную передачу данных NFC или QR-коды. Это расширяет возможности обычных электронных таблиц, превращая их в современную и мобильную систему учета, например, для малого бизнеса.
Плюсы и минусы приложений AppSheet
Сначала перечислим плюсы:
- Простота работы с информацией. Легкое и интуитивно понятное добавление или изменение цифр, текстов, времени, геолокаций, фотографий и других данных в «Google Таблицы» или Excel.
- Работа с картами. Можно отобразить данные о местоположении, оставить метки и проложить маршрут прямо в приложении.
- Наличие офлайн-режима. AppSheet позволяет проводить вычисления в таблицах приложения без доступа в интернет.
- Полная интеграция с Excel. Все формулы Excel, которые используются в таблице, также работают и в приложении AppSheet.
- Рассылка отчетов. Есть автоматическая отправка информации на почту и через push-уведомления.
- Кроссплатформенность. Приложения работают на устройствах под управлением Android, iOS, а также имеют браузерную версию.
- Гибкость. Можно создавать любые сценарии форматирования: отмечать данные цветом, иконками, использовать NFC и сканеры штрих-кодов для ввода информации, создавать графики.
- Бесплатно для 10 пользователей. Автор мобильного приложения может пригласить в команду до 9 тестировщиков на неограниченный срок. Это фактически означает бесплатную работу без ограничения функциональности.
Минусы:
- Не поддерживается русский язык. Пока что нет документации на русском и шаблонов приложений. Но компания быстро развивается и есть шанс, что разработчики решат эту проблему в скором времени.
- Долгая загрузка. Если у вас большая база данных, то приложение может синхронизироваться значительное время.
- Платная загрузка в маркеты. Если вы хотите разместить свое приложение в сервисах GooglePlay или AppStore, придется заплатить.
Создаем приложение за 8 шагов
Учет клиентов, распределение задач между сотрудниками, управление сделками – задачи, знакомые любому предпринимателю. Если свести их в единую систему, получится CRM. На рынке много готовых приложений, в том числе бесплатных – бери и пользуйся. А если нужен полный контроль над бизнес-процессами и гарантия внедрения, можно заказать интеграцию CRM с сайтом у профессионалов.
Но наша цель сейчас – просто изучить работу с AppSheet, поэтому попробуем самостоятельно создать небольшую кросс-платформенную CRM-систему. Она должна использовать данные из таблиц Excel или Google, добавлять в них новых клиентов, заполнять и редактировать информацию, ставить задачи сотрудникам и помогать контролировать дедлайны.
Шаг 1: создаем данные
Для работы нашему приложению необходимы данные, поэтому начнем с создания таблицы с заголовками, используя для этого «Google Таблицы». Советую давать листам осмысленные названия, , чтобы в процессе работы в них не запутаться.
Какого рода должны быть данные? На самом деле любые. Давайте представим,что у нас B2B компания, которая продает свои услуги другим предприятиям. Поэтому создадим для нашей CRM таблицу с названием компаний-клиентов, адресами их сайтов, e-mail и ссылками на чаты.
Будьте аккуратны: если ввести заголовки таблицы, создать приложение, а потом начать менять заголовки или добавлять новые разделы, приложение может сломаться.
В дальнейшем нам понадобятся еще данные. Чтобы не запутаться, будем создавать их не сразу, а по мере необходимости.
Шаг 2: создаем приложение
Заходим на официальный сайт AppSheet. Регистрируемся и нажимаем Start for free. После того, как выберете подходящее облачное хранилище, открывается выбор из трех категорий приложений. Вкладка Start with your own data позволит создать собственное приложение с нуля. На нее и жмем.
Интерес также представляет вкладка Start with sample app. Она позволяет использовать готовые приложения или просто заглянуть под капот некоторых интересующих вас фич.
На странице выбора данных находим только что созданный файл. Готово! Теперь мы попадаем на панель разработки, где видно, как будет выглядеть наше мобильное приложение.
Обратите внимание на кнопки View и Data. Если их использовать при настройке данных и видов, можно переключаться быстрее. Этот маленький лайфхак сбережет вам кучу времени.
В верхнем правом углу есть иконки различных устройств – с их помощью можно посмотреть, как приложение будет выглядеть на компьютере, планшете или смартфоне.
Шаг 3: разбираемся с ключами
Чтобы работать с AppSheet, нужно понимать принцип работы с ключами базы данных. Если попробовать отредактировать информацию о компании, мы увидим интересную особенность – название нельзя поменять, потому что оно является уникальным ключом. А что если компаний много и в название случайно закралась ошибка?
В этом случае требуется уникальный, неповторяющийся ключ.
Теперь добавим в базу компаний колонку с уникальными ID. Для этого нужно зайти в нашу Google-таблицу и вставить новый столбец с ID.
Далее заполняем уникальными случайными знаками те строчки, которые уже созданы. Это можно сделать двумя способами:
- Если значений мало, можно просто присвоить случайные значения нашим ID.
- Если много – использовать генераторы паролей. Однако, массово копировать их не всегда удобно.
В итоге должна получиться такая колонка:
Но это не все – сейчас программа выдает ошибку. Помните, мы обсуждали, что при добавлении новых данных, приложение ломается? Дело в том, что добавив в Google-таблицу новую колонку, вы не сообщили об этом приложению. Это можно сделать, нажав Data – Column – Regenerate Structure.
После этого должна появиться новая вкладка ID.
Теперь отмечаем новую строчку ID как ключ, а значение Label оставляем там же. Label – это этикетка. Этот параметр помогает распознать название ключа. В данном случае наша этикетка – название компании.
Раскрываем строку ID и добавляем формулу UNIQUEID() в строчку Initial value. Если этого не сделать при добавлении новой компании, значение ID будет пустым.
Не забываем скрыть ID. Это техническая информация, ее не нужно отображать пользователям. Для этого убираем флажок с Show. Пробуем ввести новую компанию – теперь название можно редактировать.
Сейчас в нашей базе автоматически сформирован новый ID. Механизм создания ключей всегда одинаков, а сами ключи нужны практически везде.
Шаг 4: добавляем возможность ставить задачи
Иногда необходимо контролировать выполнение задач. Это удобно делать в файле с базой компаний-клиентов.
Создадим специальный раздел в нашем приложении. Для этого нам понадобится еще одна таблица с данными.
Таблица создана. Разумеется, в ней могут быть любые разделы.
Теперь разберемся, в чем разница между ID задачи и обычным ID. Важно понимать, что ID задачи – это уникальное значение, которое отличает одну задачу от другой и не путать с просто ID, который нужен для присвоения задачи конкретному клиенту. В нашем случае это компания.
Присоединяем данные в приложение. Для этого заходим в раздел Data и жмем Add new table.
Выбираем нашу новую таблицу.
После обновления появится новый раздел.
Открываем вновь созданный раздел с задачами и настраиваем его.
Как видно из рисунка выше, на страничке компании ничего не изменилось и связи с задачами не возникло. Нужно настроить. Для этого перейдем в настройки строчки ID, в поле Type меняем тип на Ref, а в Source table выбираем «База компаний».
Теперь у нас появилась возможность ставить задачи по конкретной компании.
Настроим корректное отображение. Сейчас вкладка с задачами представляет собой набор непонятных символов.
Возвращаемся во вкладку «Задачи» и меняем следующие пункты:
- Переставляем Label на раздел «Задача».
- Скрываем при необходимости вкладку «Дата постановки задачи», она будет заполняться сама.
- Скрываем вкладку «ID задачи», это техническая информация. Приложение само распознало колонку «ID задачи»» как колонку с ключами, поэтому прописывать ничего не нужно. Стоит лишь проверить, чтобы в поле Initial value была формула UNIQUEID(). Если ее нет, то пропишите.
- Заходим в настройки колонки ID, находим раздел DISPLAY. В Display name прописываем имя строки. В данном случае, это «Компания».
На страничке компаний задачи тоже приняли понятный вид:
Шаг 5: добавляем сотрудников
Давайте сделаем так, чтобы задачи присваивались конкретным сотрудникам. Для этого создадим таблицу с сотрудниками. Сюда включим имя и фамилию, номер телефона, фото.
Добавляем таблицу в приложение. В данном случае ID – это имя сотрудника. Если имена повторяются, присваиваем каждому свой ID.
Добавляем связь между сотрудниками и задачами. Для этого переходим в таблицу с задачами и добавляем новую колонку с сотрудниками.
Обновляем таблицу в приложении.
В таблице «Задачи» меняем тип данных в колонке «Сотрудник» на ref и ссылаемся на таблицу с сотрудниками:
Теперь у нас появилась необходимая связь.
Часто возникает такая проблема, что вроде бы все настроил, а связь не работает.
В таком случае необходимо обновить все таблицы с помощью кнопок Regenerate Structure. Если это не помогло, проблема, скорее всего, в заголовках. При ссылках заголовки в таблицах должны быть одинаковыми.
Далее обновляем таблицы «Задачи» и «Сотрудники» в приложении с помощью клавиши Regenerate Structure. Теперь задача присвоена конкретному сотруднику.
Следом сделаем так, чтобы каждый сотрудник видел только свои задачи. Переходим Data – User Settings. Открываем любой раздел, например, Option 1.
Обязательно включаем раздел Show?, делаем type «Enum» и прописываем ссылку «Сотрудники[сотрудник]».
Теперь в приложении появилась возможность зайти как сотрудник.
Мы почти у цели. Переходим Data – Table – Таблица «Задачи» – Security – Security filter. В строке вставляем формулу: «[Сотрудник] = USERSETTINGS(Пользователь)».
После сохранения сотрудник сможет выбрать свое имя в настройках, и будут высвечиваться только персональные задачи.
Шаг 6: настраиваем пользовательский интерфейс
Теперь надо, чтобы все выглядело красиво. Для этого используем вкладку UX. Переходим UX – VIEWS. Выбираем раздел «База компаний».
Убираем лишние кнопки из данного вида. Для этого находим строчку Column order и меняем порядок расположения элементов так, как нам нужно.
Чтобы поменять иконки, нужно в DISPLAY найти раздел icons, а там уже можно выбрать необходимую иконку. Точно так же настраиваем вид «Задачи».
Добавим еще один вид – «Сотрудники». Для этого выбираем тип Desk, а в самом приложении подгружаем фотографии сотрудников.
Для того, чтобы настроить необходимые кнопки, заходим в раздел Action.
Иконки меняем в Display, в разделе icons.
Теперь сделаем так, чтобы выполненные задачи скрывались и, если сегодня дедлайн, высвечивалось бы напоминания. Для этого переходим в Data – Slice и жмем кнопку Add New Slice.
Всего у задач три статуса: активная, задача завершена или отложена. Давайте сделаем так, чтобы завершенные задачи скрывались из отображения.
Прописываем формулу: OR([Статус задачи] = «Активная», [Статус задачи]=»Отложена»). После переходим в UX во вкладку Views. Там находим вкладку Задачи. Подменим данные в вкладке For this data с «Задачи» на только что созданный Slice «Актуальные задачи».
Теперь выполненную задачу можно легко скрыть, изменив статус.
Чтобы активные и отложенные задачи разделялись в табличном виде, сгруппируем их. Для этого перейдем в вкладку Views меню настройки UX. Найдем там раздел Group by и сгруппируем по статусу задачи.
Группировка появилась. Теперь добавим выделение задачи, если у них сегодня дедлайн. Для этого переходим UX – Format rules – Add new rules. В строке формулы прописываем: «[Дедлайн]=Today()». Отмечаем колонку задачи, выбираем иконку и цвет.
Шаг 7: русифицируем. Добавляем логотип и название
Теперь осталось русифицировать наше приложение. Для этого переходим UX – Localize, там переводим названия.
Изменим логотип. Для этого переходим UX – Brand. Во вкладке App logo прикрепляем ссылку на свой логотип или выбираем системное лого.
Теперь меняем название приложения. Это делается в разделе Info – Properties. В поле Short name коротко прописываем название. Не старайтесь делать его длинным, оно не поместится на экране телефона.
Шаг 8: устанавливаем на телефон и смотрим, что у нас получилось
Чтобы установить созданное нами приложение на телефон, скачиваем AppSheet в App Store или Google Play. Заходим в него и видим список всех созданных вами приложений, находим там нашу CRM. Переходим в нее и нажимаем в настройках Add Shortcut. Теперь логотип нашего приложения появился на рабочем столе.
Итак, мы с вами создали свою простейшую CRM для любых устройств на основе «Google Таблиц». Можем добавлять в нее любые компании, отправлять письма, ставить и скрывать выполненные задачи. А если сегодня дедлайн, информация будет выделяться. Все задачи закреплены за сотрудниками, им можно звонить и отправлять СМС.
Чек-лист и мануал
Я подготовил чек-лист, чтобы вы не пропустили важные моменты.Если возникли сложности с освоением программы, можете воспользоваться подробным мануалом на русском языке. Бесплатный мануал по AppSheet.pdf
Цены и тарифы
- Бесплатный тариф. Доступен весь функционал, а 10 пользователей могут пользоваться бесплатно. Вы сможете без ограничений протестировать любые идеи и создать с ними полностью рабочее приложение.
- Тариф Premium. Стоит 5 $ за 1 активного пользователя приложения. Подойдет для тех, кто уже протестировал приложение и готов интегрировать его в свой бизнес. Этот план поддерживает все основные функции.
- Тариф Pro. Стоит 10 $ за 1 активного пользователя приложения. Включает в себя расширенный функционал – NFC и QR сканирование, вывод в магазины Google Play и App Store.
- Тариф Business. План Business обговаривается с компанией, он нужен для крупных игроков, которые хотят использовать AppSheet. Этот тариф пригодится, если необходимы персональные функции, а также машинное обучение, SQL, различная аналитика.
Вывод: использовать ли AppSheet или нет?
- Да, использовать. Если хотите большей эффективности от Excel или «Google.Таблиц», а также от себя. AppSheet может очень многое – сотни компаний, среди которых Toyota, Pepsi, Husqvarna, уже внедрили систему, которая в кратчайшие сроки позволяет обычным сотрудникам создавать умные мобильные приложение, а также освобождать программистов для более важных задач.
- Не использовать. Если вам не хочется разбираться и заморачиваться, а ваша эффективность и так в порядке.
Решать вам. А если что-то непонятно, пишите комментарии, я обязательно постараюсь разобраться и помочь. И конечно же делитесь статьей, если считаете ее полезной.
Post Views: 6,451
This post explains how to import Excel Sheets (.xlxs and .xls files) into Android SQLite Database. I have tested this code on Android 9, 10 and 11 and it works on all these Android versions. This is an updated post as my previous code is no longer supported on Android 10+ devices. I will skip the introduction on how to create a blank Android project in Android Studio.
For importing excel sheet we will be using poishadow-all.jar file library. This will be able to read .XLS as well as .XLSX file formats (which is the exact purpose of our app). You can read more on this from Official Apache Documentations.
Download the jar file add it as Android Library to your app.
build.gradle:
plugins { id 'com.android.application' } android { compileSdk 32 defaultConfig { applicationId "app.parallelcodes.excel" minSdk 21 targetSdk 32 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } buildFeatures { viewBinding true } } dependencies { implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.2' implementation 'androidx.navigation:navigation-fragment:2.3.5' implementation 'androidx.navigation:navigation-ui:2.3.5' implementation files('src\main\libs\poishadow-all.jar') testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' }
Once you have edited the gradle file, please sync it to make the library classes and methods available in your project.
Now create a class file with name DBHelper.java
and edit it as below. This is our SQLite database class. This will create, insert, delete data from our table and also help us in retrieving data from the target table. If you want to learn more on Android SQLite database, please visit this link.
My package name: app.parallelcodes.excel
DBHelper.java:
package app.parallelcodes.excel.helpers; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; public class DBHelper { String TAG = "DBAdapter"; public static final String Tablename = "MyTable1"; public static final String id = "_id";// 0 integer public static final String Company = "Company";// 1 text(String) public static final String Product = "Product";// 2 integer public static final String Price = "Price";// 3 date(String) private SQLiteDatabase db; private Database dbHelper; private static final int VERSION = 1; private static final String DB_NAME = "MyDB1.db"; public DBHelper(Context context) { dbHelper = new Database(context); } public void open() { if (null == db || !db.isOpen()) { try { db = dbHelper.getWritableDatabase(); } catch (SQLiteException sqLiteException) { } } } public void close() { if (db != null) { db.close(); } } public int insert(String table, ContentValues values) { try { db = dbHelper.getWritableDatabase(); int y = (int) db.insert(table, null, values); db.close(); Log.e("Data Inserted", "Data Inserted"); Log.e("y", y + ""); return y; } catch (Exception ex) { Log.e("Error Insert", ex.getMessage().toString()); return 0; } } public void delete() { db.execSQL("delete from " + Tablename); } public Cursor getAllRow(String table) { return db.query(table, null, null, null, null, null, id); } public ArrayList<HashMap<String, String>> getProducts() { ArrayList<HashMap<String, String>> prolist; prolist = new ArrayList<HashMap<String, String>>(); String selectQuery = "SELECT * FROM " + Tablename; SQLiteDatabase database = dbHelper.getReadableDatabase(); Cursor cursor = database.rawQuery(selectQuery, null); if (cursor.moveToFirst()) { do { HashMap<String, String> map = new HashMap<String, String>(); map.put(Company, cursor.getString(1)); map.put(Product, cursor.getString(2)); map.put(Price, cursor.getString(3)); prolist.add(map); } while (cursor.moveToNext()); } return prolist; } private class Database extends SQLiteOpenHelper { private static final int VERSION = 1; private static final String DB_NAME = "MyDB1.db"; public Database(Context context) { super(context, DB_NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { String create_sql = "CREATE TABLE IF NOT EXISTS " + Tablename + "(" + id + " INTEGER PRIMARY KEY AUTOINCREMENT," + Company + " TEXT ," + Product + " TEXT ," + Price + " TEXT " + ")"; db.execSQL(create_sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + Tablename); } } }
Create another class file with name ExcelHelper.java
and edit it as below:
ExcelHelper.java:
package app.parallelcodes.excel.helpers; import android.content.ContentValues; import android.util.Log; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import java.util.Iterator; public class ExcelHelper { public static final String Tablename = "MyTable1"; public static final String id = "_id";// 0 integer public static final String Company = "Company";// 1 text(String) public static final String Product = "Product";// 2 text(String) public static final String Price = "Price";// 3 text(String) public static void insertExcelToSqlite(DBHelper dbAdapter, Sheet sheet) { for (Iterator<Row> rit = sheet.rowIterator(); rit.hasNext(); ) { Row row = rit.next(); ContentValues contentValues = new ContentValues(); row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellType(CellType.STRING); row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellType(CellType.STRING); row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellType(CellType.STRING); contentValues.put(Company, row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()); contentValues.put(Product, row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()); contentValues.put(Price, row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()); try { if (dbAdapter.insert("MyTable1", contentValues) < 0) { return; } } catch (Exception ex) { Log.d("Exception in importing", ex.getMessage().toString()); } } } }
This class is for reading the excel sheets provided by the user into the SQLite database.
Edit your activity_mail.xml layout file as below:
res > layout > activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" android:id="@+id/main_layout" android:orientation="vertical" android:weightSum="10"> <LinearLayout android:id="@+id/lvcontainer" android:layout_width="match_parent" android:layout_height="0dp" android:layout_alignParentTop="true" android:layout_weight="0.5" android:background="#000" android:orientation="horizontal" android:padding="1dp" android:weightSum="3"> <TextView android:id="@+id/txtCompany" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:text="Company" android:textColor="#fff" android:textSize="16sp" /> <TextView android:id="@+id/txtProduct" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:padding="3dp" android:text="Product" android:textColor="#fff" android:textSize="16sp" /> <TextView android:id="@+id/txtPrice" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:padding="3dp" android:text="Price" android:textColor="#fff" android:textSize="16sp" /> </LinearLayout> <ListView android:id="@+id/lstView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@+id/lvcontainer" android:layout_weight="8.5"> </ListView> <TextView android:id="@+id/txtresulttext" android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@android:id/list" android:layout_marginLeft="5dp" android:layout_marginTop="2dp" android:layout_weight="1" android:gravity="left" android:text="" android:textColor="#FFF55F54" android:textSize="10sp" android:textStyle="italic|bold"></TextView> </LinearLayout>
This is our main layout file, it only has a listview and a label to display any errors occurred in any of the processes.
Create lst_template.xml layout file, this is the design layout file for the listView which will display excel sheet data from SQLite database.
res > layout > lst_template.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:id="@+id/lvContainer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ffe6e6e6" android:orientation="horizontal" android:scrollbars="horizontal" android:weightSum="3"> <TextView android:id="@+id/txtproductcompany" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:text="NAME" android:textColor="#000000" android:textSize="13sp" /> <TextView android:id="@+id/txtproductname" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:padding="3dp" android:text="ISSN" android:textColor="#000000" android:textSize="13sp" /> <TextView android:id="@+id/txtproductprice" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:padding="3dp" android:text="IMPACTFACTOR" android:textColor="#000000" android:textSize="13sp" /> </LinearLayout> </LinearLayout>
Edit the menu option file as below:
res > menu > menu_main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="app.parallelcodes.excel.MainActivity"> <item android:id="@+id/action_import_xlxs" android:orderInCategory="100" android:title="@string/action_import_xlxs" app:showAsAction="never" /> <item android:id="@+id/action_import_xls" android:orderInCategory="100" android:title="@string/action_import_xls" app:showAsAction="never" /> </menu>
Edit the strings.xml file as below:
res > values > strings.xml:
<resources> <string name="app_name">Excel Reader</string> <string name="action_import_xlxs">Import .XLXS</string> <string name="action_import_xls">Import .XLS</string> <string name="storage_access_required">This app requires your memory access to read excel-sheet files</string> <string name="storage_access_denied">Please goto app settings and grant memory permission. </string> <string name="storage_unavailable">Your device does not support storage</string> </resources>
Now edit the MainActivity.java class file as below:
MainActivity.java:
package app.parallelcodes.excel; import android.Manifest; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import com.google.android.material.snackbar.Snackbar; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import app.parallelcodes.excel.helpers.DBHelper; import app.parallelcodes.excel.helpers.ExcelHelper; public class MainActivity extends AppCompatActivity { static { System.setProperty( "org.apache.poi.javax.xml.stream.XMLInputFactory", "com.fasterxml.aalto.stax.InputFactoryImpl" ); System.setProperty( "org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl" ); System.setProperty( "org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl" ); } TextView lbl; DBHelper controller = new DBHelper(this); ListView lv; private static final int PERMISSION_REQUEST_MEMORY_ACCESS = 0; private static String fileType = ""; private View mLayout; private static String extensionXLS = "XLS"; private static String extensionXLXS = "XLXS"; ActivityResultLauncher<Intent> filePicker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lbl = (TextView) findViewById(R.id.txtresulttext); lv = findViewById(R.id.lstView); mLayout = findViewById(R.id.main_layout); filePicker = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent intent1 = result.getData(); Uri uri = intent1.getData(); ReadExcelFile(MainActivity.this , uri); } }); FillList(); } private boolean CheckPermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; } else { Snackbar.make(mLayout, R.string.storage_access_required, Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { requestStoragePermission(); } }).show(); return false; } } public void FillList() { try { if (controller == null) { DBHelper controller = new DBHelper(MainActivity.this); } ArrayList<HashMap<String, String>> myList = controller.getProducts(); if (myList.size() != 0) { lv = findViewById(R.id.lstView); ListAdapter adapter = new SimpleAdapter(MainActivity.this, myList, R.layout.lst_template, new String[]{DBHelper.Company, DBHelper.Product, DBHelper.Price}, new int[]{R.id.txtproductcompany, R.id.txtproductname, R.id.txtproductprice}); lv.setAdapter(adapter); } } catch (Exception ex) { Toast("FillList error: " + ex.getMessage(), ex); } } public void ReadExcelFile(Context context, Uri uri) { try { InputStream inStream; Workbook wb = null; try { inStream = context.getContentResolver().openInputStream(uri); if (fileType == extensionXLS) wb = new HSSFWorkbook(inStream); else wb = new XSSFWorkbook(inStream); inStream.close(); } catch (IOException e) { lbl.setText("First " + e.getMessage().toString()); e.printStackTrace(); } DBHelper dbAdapter = new DBHelper(this); Sheet sheet1 = wb.getSheetAt(0); dbAdapter.open(); dbAdapter.delete(); dbAdapter.close(); dbAdapter.open(); ExcelHelper.insertExcelToSqlite(dbAdapter, sheet1); dbAdapter.close(); FillList(); } catch (Exception ex) { Toast("ReadExcelFile Error:" + ex.getMessage().toString(), ex); } } public void ChooseFile() { try { Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT); fileIntent.addCategory(Intent.CATEGORY_OPENABLE); if (fileType == extensionXLS) fileIntent.setType("application/vnd.ms-excel"); else fileIntent.setType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); filePicker.launch(fileIntent); } catch (Exception ex) { Toast("ChooseFile error: " + ex.getMessage().toString(), ex); } } void Toast(String message, Exception ex) { if (ex != null) Log.e("Error", ex.getMessage().toString()); Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_MEMORY_ACCESS) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { OpenFilePicker(); } else { Snackbar.make(mLayout, R.string.storage_access_denied, Snackbar.LENGTH_SHORT) .show(); } } } private void requestStoragePermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_MEMORY_ACCESS); } else { Snackbar.make(mLayout, R.string.storage_unavailable, Snackbar.LENGTH_SHORT).show(); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_MEMORY_ACCESS); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_import_xls) { fileType = extensionXLS; OpenFilePicker(); } else if (id == R.id.action_import_xlxs) { fileType = extensionXLXS; OpenFilePicker(); } return super.onOptionsItemSelected(item); } public void OpenFilePicker() { try { if (CheckPermission()) { ChooseFile(); } } catch (ActivityNotFoundException e) { lbl.setText("No activity can handle picking a file. Showing alternatives."); } } }
The app will allow to select any excel file (.xls and .xlxs files) when the user clicks on the menu to import one, it will first check for the permission to read external storage. If the permissions are not granted, app will ask for the user permission to access external storage and then file as per the user selection.
The data from the excel sheet will be fist imported to Android SQLite database and then the newly inserted data will be display on the listView.
DOWNLOAD THIS PROJECT
Электронные таблицы используются людьми разных видов деятельности – как профессиональной, так и любительской. Но доступ к привычному Экселю на ПК есть не всегда, да и работать с телефона иногда удобнее. Есть несколько популярных табличных редакторов для Android, не уступающих по функционалу компьютерным.
Google Таблицы
Google Таблицы – это бесплатное приложение на андроид, предназначенное для работы с таблицами. Функционал позволяет:
- создавать таблицы любого размера и сложности, редактировать их;
- открывать чужие файлы соответствующего типа, к которым владелец дал доступ, редактировать и сохранять их;
- редактировать документы совместно с другими пользователями (удобно в работе и ведении проектов);
- просматривать историю изменений;
- добавлять комментарии, редактировать их, удалять;
- работать оффлайн;
- настраивать параметры автосохранения;
- вносиить в файлы формулы и диаграммы, сортировать и группировать данные, задавать параметры форматирования и настраивать автоматизацию тех или иных действий;
- работать с документами, созданными в Microsoft Excel;
- анализировать данные в документах.
Microsoft Excel: создание таблиц и работа с ними
Microsoft Excel: создание таблиц и работа с ними – это приложение на андроид для полноценной работы с таблицами, аналог компьютерной программы Microsoft Excel. Здесь можно:
- создавать простые и сложные таблицы, включать в них различные элементы (графики, диаграммы, формулы, изображения, заметки и пр.);
- работать с файлами, созданными другими пользователями;
- автоматически визуализировать данные (алгоритм умеет создавать диаграммы на основе пользовательских таблиц);
- проводить бухгалтерские или финансовые расчеты;
- составлять списки задач и изменять их в любой момент;
- рисовать графики или рукописные тексты прямо пальцем по экрану смартфона, переобразовывать рисунки в графики;
- открывать доступ к выбранным документам любому количеству пользователей (уровни доступа: только просмотр, редактирование, модерация);
- придавать таблицам практически любой вид вручную или при помощи автоматизированных настроек.
Создать и экспортировать электронную таблицу Excel
«Создать и экспортировать электронную таблицу Excel» – это бесплатное приложение на андроид, в котором доступны все базовые функции Excel, но нет дополнительных, за счет чего экономится место в телефоне. Интерфейс не перегружен и понятен даже тем пользователям, которые плохо разбираются в Excel. Здесь можно:
- создавать таблицы, аналогичные Excel, и работать с ними (добавлять и удалять столбцы и строки, работать с текстом и дополнительными элементами, вставлять формулы и выполнять соответствующие задачи и т. п.);
- включать функцию «Упрощенная форма», при которой отсекается множество возможностей, зато интерфейс становится проще и легче (актуально для работы с текстом и данными чисел);
- искать информацию по документу;
- экспортировать документы в XLS или XLSX и открывать их в Excel, даже если изначально формат был другим;
- импортировать данные Excel;
- работать в оффлайн-режиме с сохранением доступа ко всему функционалу, за исключением возможности поделиться документом с кем-либо или отправить его в печать беспроводным способом;
- использовать готовые шаблоны или создавать собственные.
Таблица заметки – Мобильная карманная база данных
«Таблица заметки – Мобильная карманная база данных» – это бесплатное приложение для андроид, предназначенное для работы с информацией, оформленной в таблицы. Здесь можно:
- создавать таблицы данных и редактировать их как самостоятельно, так и в команде одобренных пользователей;
- вводить информацию не только при помощи ручного ввода на клавиатуре телефона, но и другими способами (надиктовывать на микрофон, фотографировать данные, синхронизировать с картами или контактами, рисовать пальцем по экрану и т. п.);
- автоматически или вручную создавать графики и диаграммы для визуализации;
- включать напоминания для себя и подключенных к аккаунту коллег.
Благодаря синхронизации с другими пользователями и широкому функционалу, здесь с удобством можно:
- отправлять команды коллегам и сотрудникам;
- вести рабочие отчеты;
- контролировать подчиненных;
- вести любые базы данных и регулировать их содержание в любое время.
xlsx viewer: xls file viewer
XLSX viewer: XLS file viewer & Reader – это мобильное приложение на андроид, предназначенное для открытия и чтения форматов XLS и XLSX (то есть созданных в Excel). Оно правильно открывает таблицы с любым содержанием, даже если в них много графиков, диаграмм и других сложных для форматирования объектов в соответствии с телефонным экраном. Здесь качественно настроены функции поиска, перемещения по документу, перелистывание страниц и многое другое.
Помимо просмотра самого файла, в приложении можно посмотреть анализ содержащихся в нем данных. Есть и минимальный функционал редактирования: можно что-нибудь создать, удалить, скопировать, перенести, добавить, но более серьезных опций не предусмотрено.
При получении доступа к файлам других пользователей здесь можно следить за обновлениями в них, включив уведомления о внесенных изменениях. Это удобно для контроля каких-либо проектов и получения актуальной информации о рабочих и других процессах, не требующих серьезного вмешательства.
101 / 22 / 7 Регистрация: 10.11.2010 Сообщений: 208 |
|
1 |
|
09.11.2015, 18:41. Показов 2980. Ответов 5
Добрый вечер! Подскажите как имортировать данные из EXCEL файла в в SQLite. Есть эксель файл, с столбацми: ФИО, должность, зарплата. Большое спасибо всем откликнувшимся!)
0 |
91 / 91 / 14 Регистрация: 10.10.2015 Сообщений: 307 Записей в блоге: 1 |
|
10.11.2015, 05:44 |
2 |
Вы хотите это сделать 1 раз, или это будет часть функционала и надо будет делать в программе время от времени?
0 |
435 / 101 / 15 Регистрация: 21.02.2015 Сообщений: 845 |
|
10.11.2015, 08:08 |
3 |
с ошибками так давай свои ошибки, это интереснее чем ждать альтруистов которые будут комментарии к каждой строчке писать
0 |
3 / 3 / 1 Регистрация: 15.10.2015 Сообщений: 59 |
|
10.11.2015, 08:33 |
4 |
Если мероприятие разовое то экспортируете в CSV и любым менеджером SQLite импортируете в SQLite.
0 |
101 / 22 / 7 Регистрация: 10.11.2010 Сообщений: 208 |
|
10.11.2015, 10:59 [ТС] |
5 |
Нужно импортировать время от времени. Планировал сделать отдельную кнопку, если нужно импортнуть данные, тогда пользователь кликает и добавляет к существующей БД, новые записи.
0 |
91 / 91 / 14 Регистрация: 10.10.2015 Сообщений: 307 Записей в блоге: 1 |
|
10.11.2015, 12:36 |
6 |
0 |