Flutter 使用PDF包在PDF文档中创建动态表行
背景 My Flatter应用程序使用Flutter 使用PDF包在PDF文档中创建动态表行,flutter,flutter-web,Flutter,Flutter Web,背景 My Flatter应用程序使用pdf/pdf.dart包创建一个pdf文档,其中显示Firestore数据库集合中的信息。 PDF文档包含一个表。 我希望以动态和编程方式在表中为Firestore集合中的每条记录创建一行 当前状态 我已经能够创建PDF文档和带有预设行数的静态表。但是,我无法在表中为Firestore集合中的每条记录动态和编程地创建一行 问题 如何在表中为指定Firestore集合中的每条记录动态地、通过编程创建一行 代码片段:表格 pw.Table(border: pw
pdf/pdf.dart
包创建一个pdf文档,其中显示Firestore数据库集合中的信息。
PDF文档包含一个表。
我希望以动态和编程方式在表中为Firestore集合中的每条记录创建一行
当前状态
我已经能够创建PDF文档和带有预设行数的静态表。但是,我无法在表中为Firestore集合中的每条记录动态和编程地创建一行
问题
如何在表中为指定Firestore集合中的每条记录动态地、通过编程创建一行
代码片段:表格
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Product'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForInventoryItems(), // This triggers the Row Builder, which does not work.
])
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:invento/constants.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:universal_html/html.dart' as html;
import 'package:invento/Services/database_service.dart';
class reporting extends StatefulWidget {
@override
_reportingState createState() => _reportingState();
}
final pdf = pw.Document();
String orderNumber = '<<Order_Number>>';
String disclaimerText = '<<Disclaimer_Text>>';
String supplierEmailAddress = '<<Supplier_Name>>';
String supplierName = '<<Supplier_Email_Address>>';
String orderDate = '<<Order_Date>>';
String requiredByDate = '<<Required_By_Date>>';
String ourShipmentAddress = '<<Our_Shipment_Address>>';
String notes = '<<Notes>>';
void createPdfDocument(pw.Document pdf) {
pdf.addPage(pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: pw.EdgeInsets.all(31), // This is the page margin
build: (pw.Context context) {
return <pw.Widget>[
// Document heading with logo, disclaimer text, and title
pw.Table(
children: [
pw.TableRow(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
//
pw.Placeholder(
fallbackHeight: 50,
fallbackWidth: 75,
strokeWidth: 2),
pw.Text(
'$disclaimerText',
style: pw.TextStyle(fontSize: 8, color: PdfColors.grey),
),
],
),
pw.Column(
mainAxisAlignment: pw.MainAxisAlignment.center,
crossAxisAlignment: pw.CrossAxisAlignment.end,
children: [
pw.Text(
'Purchase Order',
style: pw.TextStyle(
fontSize: 28, color: PdfColors.deepOrange400),
),
pw.Text('Reference Number $orderNumber',
textAlign: pw.TextAlign.right),
],
),
],
),
],
//
),
// Gap
pw.Divider(color: PdfColors.white, thickness: 10),
// Supplier Details
pw.Table(// This is the starting widget for the table
children: [
pw.TableRow(
// This is the starting row for the table, within which the subsequent columns will be nested
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Purchase Order To',
style: pwTableHeadingTextStyle(),
),
pw.Text(supplierName),
pw.Text(supplierEmailAddress),
],
),
),
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Order Date',
style: pwTableHeadingTextStyle(),
),
pw.Text(orderDate),
]),
),
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Required By',
style: pwTableHeadingTextStyle(),
),
pw.Text(requiredByDate),
]),
),
],
),
]),
pw.Table(children: [
pw.TableRow(// This is the second row for the table
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Ship To',
style: pwTableHeadingTextStyle(),
),
pw.Text(ourShipmentAddress),
],
),
),
]),
//
// Now the third row of the table
]),
pw.Table(children: [
pw.TableRow(// This is the third row for the table
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Notes',
style: pwTableHeadingTextStyle(),
),
pw.Text(notes),
],
),
),
]),
]),
//Gap
pw.Divider(color: PdfColors.white, thickness: 10),
//Section Header: Stocked Items
pw.Header(text: 'Stocked Items'),
// Stocked Items Table
// Next Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Product'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForInventoryItems(),
]),
//Gap
pw.Divider(color: PdfColors.white, thickness: 10),
//Section Header: Stocked Items
pw.Header(text: 'Custom Build Items and Additional Costs'),
//
// Stocked Items Table
// Next Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Description'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForNonInventoryItems(),
]),
//
// Gap
pw.Divider(color: PdfColors.white, thickness: 10),
// Totals heading
pw.Header(text: 'Totals'),
// Totals Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(children: [
pw.Text(' '),
]),
),
paddedHeadingTextCell('Stocked Items'),
paddedHeadingTextCell('Additional Costs'),
paddedHeadingTextCell('Order Total'),
]),
//
// Now row 2 (the first row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Before Tax'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
]),
//
// Now row 4 (the third row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Tax'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
]),
//
// Now row 2 (the first row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Total'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
])
]),
//
// Divider
pw.Divider(color: PdfColors.white, thickness: 10),
pw.Paragraph(text: kLoremIpsum),
];
}));
}
pw.TableRow buildRowsForInventoryItems() {
List<pw.Column> itemList = [];
var items = DatabaseService().returnAllInventoryItemsFromAPurchaseOrder();
for (var item in items) {
final description = item.data()['description'].toString();
final unit = item.data()['unit'].toString();
final qty = item.data()['qty'].toString();
itemList.add(
pw.Column(
children: [
pw.Text(description),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(unit),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(qty),
],
),
);
}
return pw.TableRow(children: itemList);
}
buildRowsForNonInventoryItems() {
return pw.TableRow(children: [
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
]);
}
pw.TextStyle pwTableHeadingTextStyle() =>
pw.TextStyle(fontWeight: pw.FontWeight.bold);
pw.Padding paddedTextCell(String textContent) {
return pw.Padding(
padding: pw.EdgeInsets.all(4),
child:
pw.Column(crossAxisAlignment: pw.CrossAxisAlignment.start, children: [
pw.Text(textContent, textAlign: pw.TextAlign.left),
]),
);
}
pw.Padding paddedHeadingTextCell(String textContent) {
return pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(children: [
pw.Text(
textContent,
style: pwTableHeadingTextStyle(),
),
]),
);
}
class _reportingState extends State<reporting> {
@override
Widget build(BuildContext context) {
final pdf = pw.Document();
createPdfDocument(pdf);
final bytes = pdf.save();
final blob = html.Blob([bytes], 'application/pdf');
return Scaffold(
appBar: AppBar(
title: Text('Search for item'),
),
drawer: myGlobalDrawer(),
bottomNavigationBar: kStandardBottomNavigationBarForNoFAB(),
floatingActionButton: null,
body: Column(
children: [
MaterialButton(
child: Text('Create and view in browser'),
color: Colors.yellow,
onPressed: () async {
print('i got tapped');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
}),
RaisedButton(
child: Text("Create and download"),
onPressed: () {
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor =
html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'some_name.pdf';
html.document.body.children.add(anchor);
anchor.click();
html.document.body.children.remove(anchor);
html.Url.revokeObjectUrl(url);
},
),
],
),
);
}
}
代码snipbit:非功能行生成器
pw.TableRow buildRowsForInventoryItems() {
List<pw.Column> itemList = [];
var items = DatabaseService().returnAllInventoryItemsFromAPurchaseOrder();
for (var item in items) {
final description = item.data()['description'].toString();
final unit = item.data()['unit'].toString();
final qty = item.data()['qty'].toString();
itemList.add(
pw.Column(
children: [
pw.Text(description),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(unit),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(qty),
],
),
);
}
return pw.TableRow(children: itemList);
}
pw.TableRow buildRowsForInventoryItems(){
列表项列表=[];
var items=DatabaseService();
for(项目中的var项目){
最终描述=item.data()['description'].toString();
最终单位=item.data()['unit'].toString();
最终数量=item.data()['qty'].toString();
itemList.add(
pw.柱(
儿童:[
pw.文本(说明),
],
),
);
itemList.add(
pw.柱(
儿童:[
pw.文本(单位),
],
),
);
itemList.add(
pw.柱(
儿童:[
pw.文本(数量),
],
),
);
}
返回pw.TableRow(子项:itemList);
}
完整代码
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Product'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForInventoryItems(), // This triggers the Row Builder, which does not work.
])
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:invento/constants.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:universal_html/html.dart' as html;
import 'package:invento/Services/database_service.dart';
class reporting extends StatefulWidget {
@override
_reportingState createState() => _reportingState();
}
final pdf = pw.Document();
String orderNumber = '<<Order_Number>>';
String disclaimerText = '<<Disclaimer_Text>>';
String supplierEmailAddress = '<<Supplier_Name>>';
String supplierName = '<<Supplier_Email_Address>>';
String orderDate = '<<Order_Date>>';
String requiredByDate = '<<Required_By_Date>>';
String ourShipmentAddress = '<<Our_Shipment_Address>>';
String notes = '<<Notes>>';
void createPdfDocument(pw.Document pdf) {
pdf.addPage(pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: pw.EdgeInsets.all(31), // This is the page margin
build: (pw.Context context) {
return <pw.Widget>[
// Document heading with logo, disclaimer text, and title
pw.Table(
children: [
pw.TableRow(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
//
pw.Placeholder(
fallbackHeight: 50,
fallbackWidth: 75,
strokeWidth: 2),
pw.Text(
'$disclaimerText',
style: pw.TextStyle(fontSize: 8, color: PdfColors.grey),
),
],
),
pw.Column(
mainAxisAlignment: pw.MainAxisAlignment.center,
crossAxisAlignment: pw.CrossAxisAlignment.end,
children: [
pw.Text(
'Purchase Order',
style: pw.TextStyle(
fontSize: 28, color: PdfColors.deepOrange400),
),
pw.Text('Reference Number $orderNumber',
textAlign: pw.TextAlign.right),
],
),
],
),
],
//
),
// Gap
pw.Divider(color: PdfColors.white, thickness: 10),
// Supplier Details
pw.Table(// This is the starting widget for the table
children: [
pw.TableRow(
// This is the starting row for the table, within which the subsequent columns will be nested
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Purchase Order To',
style: pwTableHeadingTextStyle(),
),
pw.Text(supplierName),
pw.Text(supplierEmailAddress),
],
),
),
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Order Date',
style: pwTableHeadingTextStyle(),
),
pw.Text(orderDate),
]),
),
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Required By',
style: pwTableHeadingTextStyle(),
),
pw.Text(requiredByDate),
]),
),
],
),
]),
pw.Table(children: [
pw.TableRow(// This is the second row for the table
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Ship To',
style: pwTableHeadingTextStyle(),
),
pw.Text(ourShipmentAddress),
],
),
),
]),
//
// Now the third row of the table
]),
pw.Table(children: [
pw.TableRow(// This is the third row for the table
children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
'Notes',
style: pwTableHeadingTextStyle(),
),
pw.Text(notes),
],
),
),
]),
]),
//Gap
pw.Divider(color: PdfColors.white, thickness: 10),
//Section Header: Stocked Items
pw.Header(text: 'Stocked Items'),
// Stocked Items Table
// Next Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Product'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForInventoryItems(),
]),
//Gap
pw.Divider(color: PdfColors.white, thickness: 10),
//Section Header: Stocked Items
pw.Header(text: 'Custom Build Items and Additional Costs'),
//
// Stocked Items Table
// Next Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(
children: [
paddedHeadingTextCell('Description'),
paddedHeadingTextCell('Unit'),
paddedHeadingTextCell('Qty'),
paddedHeadingTextCell('Price'),
paddedHeadingTextCell('Discount'),
paddedHeadingTextCell('Tax'),
paddedHeadingTextCell('Total AUD'),
],
),
// Now the next table row
buildRowsForNonInventoryItems(),
]),
//
// Gap
pw.Divider(color: PdfColors.white, thickness: 10),
// Totals heading
pw.Header(text: 'Totals'),
// Totals Table
pw.Table(border: pw.TableBorder(), children: [
pw.TableRow(children: [
pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(children: [
pw.Text(' '),
]),
),
paddedHeadingTextCell('Stocked Items'),
paddedHeadingTextCell('Additional Costs'),
paddedHeadingTextCell('Order Total'),
]),
//
// Now row 2 (the first row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Before Tax'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
]),
//
// Now row 4 (the third row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Tax'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
]),
//
// Now row 2 (the first row with data)
pw.TableRow(children: [
paddedHeadingTextCell('Total'),
paddedTextCell('_______'),
paddedTextCell('_______'),
paddedTextCell('_______'),
])
]),
//
// Divider
pw.Divider(color: PdfColors.white, thickness: 10),
pw.Paragraph(text: kLoremIpsum),
];
}));
}
pw.TableRow buildRowsForInventoryItems() {
List<pw.Column> itemList = [];
var items = DatabaseService().returnAllInventoryItemsFromAPurchaseOrder();
for (var item in items) {
final description = item.data()['description'].toString();
final unit = item.data()['unit'].toString();
final qty = item.data()['qty'].toString();
itemList.add(
pw.Column(
children: [
pw.Text(description),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(unit),
],
),
);
itemList.add(
pw.Column(
children: [
pw.Text(qty),
],
),
);
}
return pw.TableRow(children: itemList);
}
buildRowsForNonInventoryItems() {
return pw.TableRow(children: [
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
paddedTextCell('_____'),
]);
}
pw.TextStyle pwTableHeadingTextStyle() =>
pw.TextStyle(fontWeight: pw.FontWeight.bold);
pw.Padding paddedTextCell(String textContent) {
return pw.Padding(
padding: pw.EdgeInsets.all(4),
child:
pw.Column(crossAxisAlignment: pw.CrossAxisAlignment.start, children: [
pw.Text(textContent, textAlign: pw.TextAlign.left),
]),
);
}
pw.Padding paddedHeadingTextCell(String textContent) {
return pw.Padding(
padding: pw.EdgeInsets.all(4),
child: pw.Column(children: [
pw.Text(
textContent,
style: pwTableHeadingTextStyle(),
),
]),
);
}
class _reportingState extends State<reporting> {
@override
Widget build(BuildContext context) {
final pdf = pw.Document();
createPdfDocument(pdf);
final bytes = pdf.save();
final blob = html.Blob([bytes], 'application/pdf');
return Scaffold(
appBar: AppBar(
title: Text('Search for item'),
),
drawer: myGlobalDrawer(),
bottomNavigationBar: kStandardBottomNavigationBarForNoFAB(),
floatingActionButton: null,
body: Column(
children: [
MaterialButton(
child: Text('Create and view in browser'),
color: Colors.yellow,
onPressed: () async {
print('i got tapped');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
}),
RaisedButton(
child: Text("Create and download"),
onPressed: () {
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor =
html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'some_name.pdf';
html.document.body.children.add(anchor);
anchor.click();
html.document.body.children.remove(anchor);
html.Url.revokeObjectUrl(url);
},
),
],
),
);
}
}
import'包装:flift/cupertino.dart';
进口“包装:颤振/材料.省道”;
导入“package:invento/constants.dart”;
输入‘package:pdf/pdf.dart’;
导入“package:pdf/widgets.dart”作为pw;
将“package:universal_html/html.dart”导入为html;
导入“包:invento/Services/database_service.dart”;
类报告扩展了StatefulWidget{
@凌驾
_reportingState createState();
}
最终pdf=pw.Document();
字符串orderNumber='';
字符串免责声明文本=“”;
字符串supplierEmailAddress='';
字符串供应商名称=“”;
字符串orderDate='';
字符串requiredByDate='';
字符串ourShipmentAddress='';
弦乐='';
作废createPdfDocument(pw.Document pdf){
pdf.addPage(pw.MultiPage(
页面格式:PdfPageFormat.a4,
边距:pw.EdgeInsets.all(31),//这是页面边距
构建:(pw.Context){
返回[
//带有徽标、免责声明文本和标题的文档标题
pw.表(
儿童:[
表行(
儿童:[
pw.柱(
crossAxisAlignment:pw.crossAxisAlignment.start,
儿童:[
//
占位符(
后备高度:50,
后备宽度:75,
冲程宽度:2),
文本(
“$免责声明文本”,
样式:pw.TextStyle(字体大小:8,颜色:PdfColors.grey),
),
],
),
pw.柱(
mainAxisAlignment:pw.mainAxisAlignment.center,
crossAxisAlignment:pw.crossAxisAlignment.end,
儿童:[
文本(
“采购订单”,
样式:pw.TextStyle(
fontSize:28,颜色:PdfColors.deepOrange400),
),
pw.Text('参考号$orderNumber',
textAlign:pw.textAlign.right),
],
),
],
),
],
//
),
//缺口
pw.分隔器(颜色:PdfColors.white,厚度:10),
//供应商详细信息
Table(//这是表的开始小部件
儿童:[
表行(
//这是表的起始行,后续列将嵌套在其中
儿童:[
填充物(
填充:所有(4)个边缘设置,
子:pw.列(
crossAxisAlignment:pw.crossAxisAlignment.start,
儿童:[
文本(
“采购订单至”,
样式:pwTableHeadingTextStyle(),
),
pw.文本(供应商名称),
pw.文本(供应商电子邮件地址),
],
),
),
填充物(
填充:所有(4)个边缘设置,
子:pw.列(
crossAxisAlignment:pw.crossAxisAlignment.start,
儿童:[
文本(
“订单日期”,
样式:pwTableHeadingTextStyle(),
),
pw.文本(订单日期),
]),
),
填充物(
填充:所有(4)个边缘设置,
子:pw.列(
crossAxisAlignment:pw.crossAxisAlignment.start,
儿童:[
文本(
'所需',
样式:pwTableHeadingTextStyle(),
),
pw.文本(按日期要求),
]),
),
],
),
]),
pw.表格(儿童:[
TableRow(//这是表的第二行
儿童:[
填充物(
填充:所有(4)个边缘设置,