- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在从事需要在 pdf 中添加条形图的项目(如果可能,可自定义 pdf)。我正在尝试使用下面的代码添加,但它不起作用
void _printScreen() {
doc.addPage(pw.MultiPage(
pageFormat: PdfPageFormat.letter
.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
header: (pw.Context context) {
if (context.pageNumber == 1) {
return null;
}
return pw.Container(
alignment: pw.Alignment.centerRight,
margin:
const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
padding:
const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
decoration: const pw.BoxDecoration(
border: pw.Border(
bottom: pw.BorderSide(
color: PdfColors.grey,
width: 0.5,
)),
),
child: pw.Text('Report',
style: pw.Theme.of(context)
.defaultTextStyle
.copyWith(color: PdfColors.grey)));
},
footer: (pw.Context context) {
return pw.Container(
alignment: pw.Alignment.centerRight,
margin: const pw.EdgeInsets.only(top: 1.0 * PdfPageFormat.cm),
child: pw.Text(
'Page ${context.pageNumber} of ${context.pagesCount}',
style: pw.Theme.of(context)
.defaultTextStyle
.copyWith(color: PdfColors.grey)));
},
build: (pw.Context context) => [
pw.Center(
child: pw.Expanded(
child: pw.Image(image),
),
)
]));
//save PDF
final String dir = (await getExternalStorageDirectory()).path;
final String path =
'$dir/myreport${DateTime.now().toIso8601String()}.pdf';
final File file = File(path);
await file.writeAsBytes(await doc.save());
snackbarMessage(
message: "Report Saved Successfully.",
icon: FontAwesomeIcons.infoCircle);
return doc.save();
});
}
如果有人实现了这样的事情(在 pdf 中添加图表)请分享您的答案..提前谢谢您:)
最佳答案
你好,我实际上是通过在 pdf 中添加我想要的聊天“图像”来解决这个问题的。你需要这些包来完成它
flutter_email_sender: ^5.0.2
fl_chart: ^0.46.0
screenshot: ^1.2.3
pdf: ^3.3.0
path_provider: ^2.0.9
permission_handler: ^9.2.0
我下面的示例需要其中一些。我的示例创建一个 pdf(将其保存到设备)并打开电子邮件以将其发送给用户。
您的 list 中还需要这些权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
pdf_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'dart:io';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:screenshot/screenshot.dart';
import 'package:test_project_pdf/chart_for_pdf.dart';
class PdfPage extends StatelessWidget {
const PdfPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () async {
if (await Permission.storage.isGranted) {
await _pdfResults(context);
} else {
await [Permission.storage].request();
if (await Permission.storage.isGranted) {
await _pdfResults(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Need permissions"),
));
}
}
},
child: Center(
child: Container(
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(32)),
child: const Text(
"Send e-mail",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18),
)),
),
);
}
Future _pdfResults(context) async {
var pdf = pw.Document();
ScreenshotController screenshotController = ScreenshotController();
final bytes = await screenshotController.captureFromWidget(MediaQuery(data: const MediaQueryData(), child: ChartForPdf()));
pdf.addPage(
pw.MultiPage(
pageFormat: PdfPageFormat.a4,
margin: const pw.EdgeInsets.all(32),
build: (pw.Context context) {
return <pw.Widget>[
pw.Column(
children: [
pw.Center(
child: pw.Container(
height: 700,
width: 1080,
child: pw.Expanded(
child: pw.Image(pw.MemoryImage(bytes)),
),
),
),
],
),
];
},
),
);
await savePdf(pdf, context);
}
Future<String> savePdf(pw.Document pdf, var context) async {
var path;
late File file;
Directory directory;
if (Platform.isAndroid) {
path = (await getExternalStorageDirectory())!.path;
file = File("$path/best_pdf.pdf");
} else if (Platform.isIOS) {
path = await getApplicationDocumentsDirectory();
directory = await Directory("${path.path}/best_pdfs").create();
file = File("${directory.path}/best_pdf.pdf");
}
if (await file.exists()) {
try {
await file.delete();
} on Exception catch (e) {
print(e);
}
}
await file.writeAsBytes(await pdf.save());
await send(file.path, context);
return file.path;
}
Future<void> send(String path, var context) async {
final Email email = Email(
subject: "Mood Chart",
recipients: [""],
attachmentPaths: [path],
isHTML: false,
);
try {
await FlutterEmailSender.send(email);
// platformResponse = 'Επιτυχία';
} on PlatformException catch (error) {
if (error.message == "No email clients found!") {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("Device has no email"),
duration: Duration(seconds: 2)));
}
}
}
}
chart_for_pdf.dart
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class ChartForPdf extends StatelessWidget {
final Color barBackgroundColor = const Color(0xff72d8bf);
final Duration animDuration = const Duration(milliseconds: 250);
int touchedIndex = -1;
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)),
color: const Color(0xff81e5cd),
child: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Text(
'Mingguan',
style: TextStyle(
color: Color(0xff0f4a3c),
fontSize: 24,
fontWeight: FontWeight.bold),
),
const SizedBox(
height: 4,
),
const Text(
'Grafik konsumsi kalori',
style: TextStyle(
color: Color(0xff379982),
fontSize: 18,
fontWeight: FontWeight.bold),
),
const SizedBox(
height: 38,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: BarChart( mainBarData(),
swapAnimationDuration: animDuration,
),
),
),
const SizedBox(
height: 12,
),
],
),
),
],
),
),
);
}
BarChartGroupData makeGroupData(
int x,
double y, {
bool isTouched = false,
Color barColor = Colors.white,
double width = 22,
List<int> showTooltips = const [],
}) {
return BarChartGroupData(
x: x,
barRods: [
BarChartRodData(
toY: isTouched ? y + 1 : y,
colors: isTouched ? [Colors.yellow] : [barColor],
width: width,
borderSide: isTouched
? BorderSide(color: Colors.yellow, width: 1)
: const BorderSide(color: Colors.white, width: 0),
backDrawRodData: BackgroundBarChartRodData(
show: true,
toY: 20,
colors: [barBackgroundColor],
),
),
],
showingTooltipIndicators: showTooltips,
);
}
List<BarChartGroupData> showingGroups() => List.generate(7, (i) {
switch (i) {
case 0:
return makeGroupData(0, 5, isTouched: i == touchedIndex);
case 1:
return makeGroupData(1, 6.5, isTouched: i == touchedIndex);
case 2:
return makeGroupData(2, 5, isTouched: i == touchedIndex);
case 3:
return makeGroupData(3, 7.5, isTouched: i == touchedIndex);
case 4:
return makeGroupData(4, 9, isTouched: i == touchedIndex);
case 5:
return makeGroupData(5, 11.5, isTouched: i == touchedIndex);
case 6:
return makeGroupData(6, 6.5, isTouched: i == touchedIndex);
default:
return throw Error();
}
});
BarChartData mainBarData() {
return BarChartData(
barTouchData: BarTouchData(
touchTooltipData: BarTouchTooltipData(
tooltipBgColor: Colors.blueGrey,
getTooltipItem: (group, groupIndex, rod, rodIndex) {
String weekDay;
switch (group.x.toInt()) {
case 0:
weekDay = 'Monday';
break;
case 1:
weekDay = 'Tuesday';
break;
case 2:
weekDay = 'Wednesday';
break;
case 3:
weekDay = 'Thursday';
break;
case 4:
weekDay = 'Friday';
break;
case 5:
weekDay = 'Saturday';
break;
case 6:
weekDay = 'Sunday';
break;
default:
throw Error();
}
return BarTooltipItem(
weekDay + '\n',
const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
children: <TextSpan>[
TextSpan(
text: (rod.toY - 1).toString(),
style: const TextStyle(
color: Colors.yellow,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
],
);
}),
),
titlesData: FlTitlesData(
show: true,
rightTitles: SideTitles(showTitles: false),
topTitles: SideTitles(showTitles: false),
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (context, value) => const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14),
margin: 16,
getTitles: (double value) {
switch (value.toInt()) {
case 0:
return 'M';
case 1:
return 'T';
case 2:
return 'W';
case 3:
return 'T';
case 4:
return 'F';
case 5:
return 'S';
case 6:
return 'S';
default:
return '';
}
},
),
leftTitles: SideTitles(
showTitles: false,
),
),
borderData: FlBorderData(
show: false,
),
barGroups: showingGroups(),
gridData: FlGridData(show: false),
);
}
BarChartData randomData() {
return BarChartData(
barTouchData: BarTouchData(
enabled: false,
),
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (context, value) => const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14),
margin: 16,
getTitles: (double value) {
switch (value.toInt()) {
case 0:
return 'M';
case 1:
return 'T';
case 2:
return 'W';
case 3:
return 'T';
case 4:
return 'F';
case 5:
return 'S';
case 6:
return 'S';
default:
return '';
}
},
),
leftTitles: SideTitles(
showTitles: false,
),
topTitles: SideTitles(
showTitles: false,
),
rightTitles: SideTitles(
showTitles: false,
)),
borderData: FlBorderData(
show: false,
),
barGroups: List.generate(7, (i) {
switch (i) {
case 0:
return makeGroupData(0, Random().nextInt(15).toDouble() + 6,
barColor: Colors.blue);
case 1:
return makeGroupData(1, Random().nextInt(15).toDouble() + 6,
barColor: Colors.amber);
case 2:
return makeGroupData(2, Random().nextInt(15).toDouble() + 6,
barColor: Colors.deepOrange);
case 3:
return makeGroupData(3, Random().nextInt(15).toDouble() + 6,
barColor: Colors.pink);
case 4:
return makeGroupData(4, Random().nextInt(15).toDouble() + 6,
barColor: Colors.red);
case 5:
return makeGroupData(5, Random().nextInt(15).toDouble() + 6,
barColor: Colors.green);
case 6:
return makeGroupData(6, Random().nextInt(15).toDouble() + 6,
barColor: Colors.blueGrey);
default:
return throw Error();
}
}),
gridData: FlGridData(show: false),
);
}
}
主.dart
import 'package:flutter/material.dart';
import 'package:test_project_pdf/pdf_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(
body: Center (child: PdfPage()),
),
);
}
}
关于flutter - 使用 flutter 在 pdf 中添加图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68572148/
我的代码有一些问题。我正在尝试遍历包含许多 PDF 的 Drive 文件夹,然后将它们合并为一个文件。当我使用我的代码时,它只是为 Drive 文件夹中的最后一个 PDF 创建一个 PDF,而不是按预
我从 PDF Specification 获取了 PDF 规范中的最小 PDF 示例。 ,将其复制到记事本,将文件重命名为扩展名为 .pdf。 我可以用其他 PDF 查看器(PDF-XChange、S
感谢您在以下方面的帮助: 我有 2 个部分可访问的 PDF(包含标签),我想使用一些命令行工具(如 PDFtk 或 Ghostscript,或任何 Perl 模块)将它们连接起来: 我已经尝试使用 P
我想使用 ghostscript 将矢量 pdf 转换为光栅 pdf(即光栅化矢量 pdf)。但是即使我添加了解析参数 -r300,我也找不到合适的参数来执行此操作。 我使用的代码是-dSAFER -
我无法在 FAQ 中找到这个功能是否存在于 API 中,尽管它在书中提到作为潜在可用的东西。有没有人有任何实现此功能的经验? 最佳答案 在 This thread (日期为 2007 年 6 月)Pa
我要放文件sample.pdf在我的网站上,并希望使用 pdf.js 显示它.我想要的是显示我自己的文件,如 demo ,带有工具栏,放大/缩小等。到目前为止,我还不能这样做。 我确实检查了 hell
我知道这可能不是严格意义上的编程问题(也许是,我不知道)但我在尝试转换常规 pdf(带有超链接、书签、图像、嵌入字体等)时遇到了严重问题.) 转换为 PDF/A-1 格式。 当我用 pdfaPilot
这是 PDF.js 网站 https://github.com/mozilla/pdf.js 我正在搜索和阅读很多文章,大多数编码都是将 pdf 导入 pdf.js 并在浏览器上显示,我不明白是不是
谁能建议我如何将扫描图像转换为可搜索图像或如何将扫描 pdf 转换为可搜索 pdf? 很长一段时间以来,我一直陷入这种情况。 我已经在 ubuntu 中尝试过 pdfocr 应用程序,但没有成功。 最
作为我对客户端/服务器 pdf 签名研究的一部分,我测试了 itext pdf 延迟签名示例。不幸的是,我生成的 pdf 即合并空签名 pdf 和哈希值的输出显示无效签名。 我的代码片段如下 cla
我想将一个 PDF 页面插入到另一个已缩放的 PDF 页面中。我想使用 iTextSharp 来实现此目的。 我有一个矢量绘图,可以导出为单页 PDF 文件。我想将此文件添加到其他 PDF 文档的页面
作为我对客户端/服务器 pdf 签名研究的一部分,我测试了 itext pdf 延迟签名示例。不幸的是,我生成的 pdf 即合并空签名 pdf 和哈希值的输出显示无效签名。 我的代码片段如下 cla
我想为 Kindle 转换电子书。我尝试使用 Calibre 将具有复杂格式样式和图像的基于两种语言的基于文本的大型 PDF 电子书转换为适用于 Kindle 的 AZW3 电子书,并且还尝试了亚马逊
我在 Google Chrome 中显示 pdf 时遇到问题。问题是 Chrome 将 pdf 的某些页面显示为黑色。 启用 Chrome PDF 查看器时会发生这种情况。如果我禁用此插件并使用 Ad
我确信这个问题无处不在,尽管我似乎找不到答案。我希望我的 PDF 文档在 PDF 阅读器中显示时没有空白页,但随后在封面后打印空白页,这样打印出来的文档在右侧甚至左侧都有奇数页。还有其他人遇到过这个问
我需要自动裁剪 pdf 文件(去除白边)。到目前为止,我尝试了两种并不完美的工具: pdf裁剪 问题:它不会裁剪某些 pdf。 pdf-crop-margins 问题:有时它裁剪得太多(精细的细节)。
This PDF由几个源文件组成。其中五个是包含 alpha channel 的 PNG。一种是没有 alpha channel 的 PNG。最后一 block 是带有透明效果的 Photoshop
我的团队将内部 wiki 页面用于各种内容。这些页面是使用 MediaWiki 创建的。我想知道是否有任何方法可以将 wiki 页面转换为 PDF 格式。我必须用它来将用户文档转换为 PDF 格式,以
我希望能够从我可能在数据库或 xml 或任何其他结构化形式中拥有的数据生成高度图形化(也包含大量文本内容)的 PDF 文件。 目前,我们的平面设计师在将内容作为 MS Word 文档后,在 Photo
我正在寻找可以帮助我找到重复 PDF 的实用程序。问题:我有 1000 个 PDF 文件。有些是重复的。由于不同的文件名和文件大小的微小差异,它们不容易被检测到。是否有实用程序/算法/库可以帮助我找到
我是一名优秀的程序员,十分优秀!