Firebase 如何在Flatter中创建从Firestore到CSV文件的数据表
好的,故事是这样的:Firebase 如何在Flatter中创建从Firestore到CSV文件的数据表,firebase,csv,flutter,pdf,google-cloud-firestore,Firebase,Csv,Flutter,Pdf,Google Cloud Firestore,好的,故事是这样的: import 'dart:io'; import 'package:basic_utils/basic_utils.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:csv/csv.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.d
import 'dart:io';
import 'package:basic_utils/basic_utils.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:csv/csv.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
class AdminPage extends StatefulWidget {
static final TextEditingController _emailController = TextEditingController();
@override
_AdminPageState createState() => _AdminPageState();
}
class _AdminPageState extends State<AdminPage> {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
DocumentSnapshot _currentDocument;
String filePath;
String currentProcess;
bool isProcessing = false;
Future<String> get _localPath async {
final directory = await getApplicationSupportDirectory();
return directory.absolute.path;
}
Future<File> get _localFile async {
final path = await _localPath;
filePath = '$path/clouddata.csv';
return File('$path/clouddata.csv').create();
}
List<List<dynamic>> rows = List<List<dynamic>>();
getCsv(DocumentSnapshot document) async {
setState(() {
currentProcess = "Getting data from the cloud";
isProcessing = true;
});
Firestore.instance
.collection('Airline_Transactions').document(_currentDocument.documentID)
.snapshots();
{
setState(() {
currentProcess = "Decoding data";
});
}
rows.add([
"Date",
"Airline",
"Flight Number",
"Terminal",
"pax",
"Infant",
"Transit",
]);
if (document.data != null) {
for (int i = 0; i < document.data.length; i++) {
List<dynamic> row = List<dynamic>();
row.add(document.data[i]["date"].toString());
row.add(document.data[i]["airline"].toString());
row.add(document.data[i]["flight_number"].toString());
row.add(document.data[i]["terminal"].toString());
row.add(document.data[i]["pax"].toString());
row.add(document.data[i]["infant"].toString());
row.add(document.data[i]["transit"].toString());
rows.add(row);
}
File f = await _localFile.whenComplete(() {
setState(() {
currentProcess = "Writing to CSV";
});
});
String csv = const ListToCsvConverter().convert(rows);
f.writeAsString(csv);
filePath = f.uri.path;
}
}
sendMailAndAttachment() async {
final Email email = Email(
body:
'Data Collected and Compiled by the Datum App. <br> A CSV file is attached to this <b>mail</b> <hr><br> Compiled at ${DateTime.now()}',
subject: 'Datum Entry for ${DateTime.now().toString()}',
recipients: [AdminPage._emailController.text],
isHTML: true,
attachmentPath: filePath,
);
await FlutterEmailSender.send(email);
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text("Datum Dash")),
body: ListView(
padding: EdgeInsets.only(top: 45, right: 10, left: 10, bottom: 20),
children: <Widget>[
Text("Welcome to DashBoard",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500)),
Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: TextFormField(
controller: AdminPage._emailController,
validator: (str) => (str.length == 0)
? "please enter your email"
: (!EmailUtils.isEmail(str))
? "please enter a valid email"
: null,
decoration: InputDecoration(
labelText: "Enter your email",
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Theme.of(context).accentColor,
child: Text("Compile and Send"),
onPressed: (isProcessing)
? null
: () async {
if (_formkey.currentState.validate()) {
try {
final result =
await InternetAddress.lookup('google.com');
if (result.isNotEmpty &&
result[0].rawAddress.isNotEmpty) {
await getCsv(_currentDocument).then((v) {
setState(() {
currentProcess =
"Compiling and sending mail";
});
sendMailAndAttachment().whenComplete(() {
setState(() {
isProcessing = false;
});
_scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text("Data Sent"),
));
});
});
}
} on SocketException catch (_) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(
"Connect your device to the internet, and try again"),
));
}
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Visibility(
visible: (isProcessing) ? true : false,
child: Row(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
height: 25,
width: 25),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("$currentProcess"),
)
],
),
),
),
],
),
)
],
),
);
}
}
我的应用程序可以创建报告,现在这些报告整齐地显示在表格中。数据正在从firestore流式传输
问题:
import 'dart:io';
import 'package:basic_utils/basic_utils.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:csv/csv.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
class AdminPage extends StatefulWidget {
static final TextEditingController _emailController = TextEditingController();
@override
_AdminPageState createState() => _AdminPageState();
}
class _AdminPageState extends State<AdminPage> {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
DocumentSnapshot _currentDocument;
String filePath;
String currentProcess;
bool isProcessing = false;
Future<String> get _localPath async {
final directory = await getApplicationSupportDirectory();
return directory.absolute.path;
}
Future<File> get _localFile async {
final path = await _localPath;
filePath = '$path/clouddata.csv';
return File('$path/clouddata.csv').create();
}
List<List<dynamic>> rows = List<List<dynamic>>();
getCsv(DocumentSnapshot document) async {
setState(() {
currentProcess = "Getting data from the cloud";
isProcessing = true;
});
Firestore.instance
.collection('Airline_Transactions').document(_currentDocument.documentID)
.snapshots();
{
setState(() {
currentProcess = "Decoding data";
});
}
rows.add([
"Date",
"Airline",
"Flight Number",
"Terminal",
"pax",
"Infant",
"Transit",
]);
if (document.data != null) {
for (int i = 0; i < document.data.length; i++) {
List<dynamic> row = List<dynamic>();
row.add(document.data[i]["date"].toString());
row.add(document.data[i]["airline"].toString());
row.add(document.data[i]["flight_number"].toString());
row.add(document.data[i]["terminal"].toString());
row.add(document.data[i]["pax"].toString());
row.add(document.data[i]["infant"].toString());
row.add(document.data[i]["transit"].toString());
rows.add(row);
}
File f = await _localFile.whenComplete(() {
setState(() {
currentProcess = "Writing to CSV";
});
});
String csv = const ListToCsvConverter().convert(rows);
f.writeAsString(csv);
filePath = f.uri.path;
}
}
sendMailAndAttachment() async {
final Email email = Email(
body:
'Data Collected and Compiled by the Datum App. <br> A CSV file is attached to this <b>mail</b> <hr><br> Compiled at ${DateTime.now()}',
subject: 'Datum Entry for ${DateTime.now().toString()}',
recipients: [AdminPage._emailController.text],
isHTML: true,
attachmentPath: filePath,
);
await FlutterEmailSender.send(email);
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text("Datum Dash")),
body: ListView(
padding: EdgeInsets.only(top: 45, right: 10, left: 10, bottom: 20),
children: <Widget>[
Text("Welcome to DashBoard",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500)),
Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: TextFormField(
controller: AdminPage._emailController,
validator: (str) => (str.length == 0)
? "please enter your email"
: (!EmailUtils.isEmail(str))
? "please enter a valid email"
: null,
decoration: InputDecoration(
labelText: "Enter your email",
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Theme.of(context).accentColor,
child: Text("Compile and Send"),
onPressed: (isProcessing)
? null
: () async {
if (_formkey.currentState.validate()) {
try {
final result =
await InternetAddress.lookup('google.com');
if (result.isNotEmpty &&
result[0].rawAddress.isNotEmpty) {
await getCsv(_currentDocument).then((v) {
setState(() {
currentProcess =
"Compiling and sending mail";
});
sendMailAndAttachment().whenComplete(() {
setState(() {
isProcessing = false;
});
_scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text("Data Sent"),
));
});
});
}
} on SocketException catch (_) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(
"Connect your device to the internet, and try again"),
));
}
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Visibility(
visible: (isProcessing) ? true : false,
child: Row(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
height: 25,
width: 25),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("$currentProcess"),
)
],
),
),
),
],
),
)
],
),
);
}
}
有一个必备功能,可以将报告从应用程序中导出,比如发送电子邮件。所以我尝试将其导出为PDF,但它只保存当前在scaffold中查看的内容,这意味着需要滚动才能显示/查看的行和列不会导出为PDF。目前,我正试图对包含firestore实例的所有数据流的CSV文件执行相同的操作,在数据表视图中对其进行格式化
**用完整的代码编辑**
下面是代码:
import 'dart:io';
import 'package:basic_utils/basic_utils.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:csv/csv.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
class AdminPage extends StatefulWidget {
static final TextEditingController _emailController = TextEditingController();
@override
_AdminPageState createState() => _AdminPageState();
}
class _AdminPageState extends State<AdminPage> {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
DocumentSnapshot _currentDocument;
String filePath;
String currentProcess;
bool isProcessing = false;
Future<String> get _localPath async {
final directory = await getApplicationSupportDirectory();
return directory.absolute.path;
}
Future<File> get _localFile async {
final path = await _localPath;
filePath = '$path/clouddata.csv';
return File('$path/clouddata.csv').create();
}
List<List<dynamic>> rows = List<List<dynamic>>();
getCsv(DocumentSnapshot document) async {
setState(() {
currentProcess = "Getting data from the cloud";
isProcessing = true;
});
Firestore.instance
.collection('Airline_Transactions').document(_currentDocument.documentID)
.snapshots();
{
setState(() {
currentProcess = "Decoding data";
});
}
rows.add([
"Date",
"Airline",
"Flight Number",
"Terminal",
"pax",
"Infant",
"Transit",
]);
if (document.data != null) {
for (int i = 0; i < document.data.length; i++) {
List<dynamic> row = List<dynamic>();
row.add(document.data[i]["date"].toString());
row.add(document.data[i]["airline"].toString());
row.add(document.data[i]["flight_number"].toString());
row.add(document.data[i]["terminal"].toString());
row.add(document.data[i]["pax"].toString());
row.add(document.data[i]["infant"].toString());
row.add(document.data[i]["transit"].toString());
rows.add(row);
}
File f = await _localFile.whenComplete(() {
setState(() {
currentProcess = "Writing to CSV";
});
});
String csv = const ListToCsvConverter().convert(rows);
f.writeAsString(csv);
filePath = f.uri.path;
}
}
sendMailAndAttachment() async {
final Email email = Email(
body:
'Data Collected and Compiled by the Datum App. <br> A CSV file is attached to this <b>mail</b> <hr><br> Compiled at ${DateTime.now()}',
subject: 'Datum Entry for ${DateTime.now().toString()}',
recipients: [AdminPage._emailController.text],
isHTML: true,
attachmentPath: filePath,
);
await FlutterEmailSender.send(email);
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text("Datum Dash")),
body: ListView(
padding: EdgeInsets.only(top: 45, right: 10, left: 10, bottom: 20),
children: <Widget>[
Text("Welcome to DashBoard",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500)),
Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: TextFormField(
controller: AdminPage._emailController,
validator: (str) => (str.length == 0)
? "please enter your email"
: (!EmailUtils.isEmail(str))
? "please enter a valid email"
: null,
decoration: InputDecoration(
labelText: "Enter your email",
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Theme.of(context).accentColor,
child: Text("Compile and Send"),
onPressed: (isProcessing)
? null
: () async {
if (_formkey.currentState.validate()) {
try {
final result =
await InternetAddress.lookup('google.com');
if (result.isNotEmpty &&
result[0].rawAddress.isNotEmpty) {
await getCsv(_currentDocument).then((v) {
setState(() {
currentProcess =
"Compiling and sending mail";
});
sendMailAndAttachment().whenComplete(() {
setState(() {
isProcessing = false;
});
_scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text("Data Sent"),
));
});
});
}
} on SocketException catch (_) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(
"Connect your device to the internet, and try again"),
));
}
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Visibility(
visible: (isProcessing) ? true : false,
child: Row(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
height: 25,
width: 25),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("$currentProcess"),
)
],
),
),
),
],
),
)
],
),
);
}
}
导入'dart:io';
导入“包:basic_utils/basic_utils.dart”;
导入“包:cloud_firestore/cloud_firestore.dart”;
导入“包:csv/csv.dart”;
进口“包装:颤振/材料.省道”;
导入“package:path_provider/path_provider.dart”;
导入“package:flatter_email_sender/flatter_email_sender.dart”;
类AdminPage扩展了StatefulWidget{
静态最终TextEditingController _emailController=TextEditingController();
@凌驾
_AdminPageState createState()=>\u AdminPageState();
}
类_AdminPageState扩展了状态{
最终的GlobalKey _formkey=GlobalKey();
文档快照_currentDocument;
字符串文件路径;
字符串处理;
bool isProcessing=false;
未来获取\u本地路径异步{
最终目录=等待getApplicationSupportDirectory();
返回directory.absolute.path;
}
未来获取\u本地文件异步{
最终路径=等待_localPath;
filePath='$path/clouddata.csv';
返回文件(“$path/clouddata.csv”).create();
}
列表行=列表();
getCsv(文档快照文档)异步{
设置状态(){
currentProcess=“从云获取数据”;
isProcessing=true;
});
Firestore.instance
.collection(“航空公司交易”).document(\u currentDocument.documentID)
.快照();
{
设置状态(){
currentProcess=“解码数据”;
});
}
行。添加([
“日期”,
“航空公司”,
“航班号”,
“终端”,
“和平”,
“婴儿”,
“过境”,
]);
if(document.data!=null){
for(int i=0;i此邮件附有一个CSV文件。
在${DateTime.now()}编译,
主题:${DateTime.now().toString()}的数据项,
收件人:[AdminPage.\u emailController.text],
伊什特尔:没错,
attachmentPath:filePath,
);
等待电子邮件发件人。发送(电子邮件);
}
GlobalKey _scaffoldKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回脚手架(
钥匙:_scaffoldKey,
appBar:appBar(标题:文本(“基准线”)),
正文:ListView(
填充:仅限边集(顶部:45,右侧:10,左侧:10,底部:20),
儿童:[
文本(“欢迎使用仪表板”,
样式:TextStyle(fontSize:30,fontWeight:fontWeight.w500)),
形式(
键:_formkey,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
填充物(
填充:仅限常量边集(顶部:20.0),
子项:TextFormField(
控制器:AdminPage.\u emailController,
验证程序:(str)=>(str.length==0)
?“请输入您的电子邮件”
:(!EmailUtils.isEmail(str))
?“请输入有效的电子邮件”
:null,
装饰:输入装饰(
labelText:“输入您的电子邮件”,
边框:OutlineInputBorder(),
后缀:图标(Icons.email)),
),
),
填充物(
填充:仅限常量边集(顶部:8.0),
孩子:升起按钮(
颜色:主题。背景。强调颜色,
子项:文本(“编译并发送”),
onPressed:(正在处理)
无效的
:()异步{
if(_formkey.currentState.validate()){
试一试{
最终结果=
等待InternetAddress.lookup('google.com');
如果(result.isNotEmpty)&&
结果[0].rawAddress.isNotEmpty){
等待getCsv(_currentDocument)。然后((v){
设置状态(){
当前进程=
“编写和发送邮件”;
});
sendMailAndAttachment()。完成时(){
设置状态(){
isProcessing=false;
});
_sc