I use this library https://pub.dev/packages/pdf to generate a PDF. The problem is that I can’t manage to add photos to my PDF. The path for each photo is saved in a List of objects. This is how I try to approach the implementation:
import 'package:pdf/widgets.dart' as pw;
Future<void> generatePDF() async {
pdf = pw.Document();
pdf.addPage(
pw.MultiPage(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) => [
pw.Partitions(
children: [
pw.Partition(
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: <pw.Widget>[
/// Photos list
pw.ListView.builder(
itemCount: 1,
itemBuilder: (pw.Context context, int index) {
return pw.Column(
children: _photosList
?.map(
(photo) async => pw.Column(
children: <pw.Widget>[
pw.Text(
"Photo id: ${photo.photoId} - Photo type: ${photo.photoType}"), // This is displayed correctly for each photo
pw.Image(
pw.MemoryImage(
(await rootBundle
.load('${photo.photoPath}')) // This is not working because the photos are not in rootBundle and I can't find a solution to replace this line
.buffer
.asUint8List(),
),
),
],
),
)
?.toList() ??
[],
);
},
),
],
),
),
],
),
],
),
);
print('PDF Generated');
}
Output:
Import dart:io
import 'dart:io';
If you have a path, you can make a File out of it.
File photo1 = File(photo.photoPath);
Then, you can load in that File to the PDF by using the following statements:
MemoryImage memoryImage = pw.MemoryImage(photo1.readAsBytesSync()); //you could use async as well
This leaves you with a MemoryImage from you photoPath. Then you can simply add it:
pw.Image(memoryImage)
Related
list all video files from a specific folder from internal storage and display them in flutter.
i want to create an app to list all videos in internal storage and show them in gridview and play that video
To get all the files from the storage you can use path_provider flutter package. With this, get the folder path, extract all the files with an extension of .mp4 (video file), and store it in List.
List<FileSystemEntity> _files = [];
void _getFiles() async {
Directory directory = await getExternalStorageDirectory();
List<FileSystemEntity> files = directory.listSync().where((entity) => entity.path.endsWith('.mp4')).toList();
setState(() {
_files = files;
});
}
Then you can use video_player Flutter package to play the video.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
),
itemCount: _files.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
setState(() {
_controller = VideoPlayerController.file(_files[index])
..initialize().then((_) {
_controller.play();
});
});
},
child: Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.video_library,
size: 50,
),
SizedBox(height: 10),
Text(_files[index].path.split('/').last),
],
),
),
);
},
);
I'm trying to find how could i can load network image in my Pdf. I have a list of details including an image urls. and i want to create the same list in a pdf with multiple pages.
So, i used pdf plugin to create the pages. All the details where loaded except the images. since the images should be downloaded from the server. The pdf pages are created with special widget elements (as like the flutter elements, but call with a prefix) and there is no FutureBuilder to manage the await functions.
Could anybody please help. I really stuck on this.
generatePdf(List<BhaiModel> bhaiList) async {
itemCount = 0;
List<BhaiModel> pageItems = [];
for (int i = 0; i < bhaiList.length; i++) {
if ((i + 1) % 5 == 0) {
pageItems.add(bhaiList[i]);
createPage(pageItems);
pageItems = [];
} else {
pageItems.add(bhaiList[i]);
if (i + 1 == bhaiList.length) {
createPage(pageItems);
}
}
}
final output = await getApplicationDocumentsDirectory();
final file = File("${output.path}/sample.pdf");
await file
.writeAsBytes(await pdf.save())
.then((value) => print("pdf saved"));
OpenFile.open("${output.path}/sample.pdf");
print(output.path);
}
createPage(List<BhaiModel> pageItems) async {
pdf.addPage(pw.Page(
pageFormat: PdfPageFormat.a4,
margin: const pw.EdgeInsets.all(30),
build: (pw.Context context) => pw.Column(
mainAxisAlignment: pageItems.length == 5
? pw.MainAxisAlignment.spaceEvenly
: pw.MainAxisAlignment.start,
children: pageItems.map((e) => customBhaiPdfItem(e)).toList())));
}
pw.Row customBhaiPdfItem(BhaiModel bhai) {
itemCount++;
final netImage = await networkImage(bhai.photo_url);
//THIS MAKE THE FUNCTION ASYNC
return pw.Row(children: [
pw.Container(
width: 530,
padding: const pw.EdgeInsets.all(8),
decoration: pw.BoxDecoration(border: pw.Border.all()),
child: pw.Row(mainAxisSize: pw.MainAxisSize.min, children: [
pw.Container(
color: const PdfColor(0.5, 0.5, 0.5),
width: 120,
height: 120,
child: pw.Image(netImage)),
pw.SizedBox(width: 20),
pw.Flexible(
child: pw.Container(
child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [
CustomRowText("No.", "$itemCount"),
CustomRowText("Name", "${bhai.first_name} ${bhai.last_name}"),
CustomRowText("Adhaar No.", bhai.adhaar_no),
CustomRowText("Mobile No.", bhai.mobile_no),
CustomRowText("Checkout At.",
bhai.last_checkout.replaceFirst('T', ' ').split('.')[0]),
CustomRowText("Address", bhai.address),
CustomRowText("City", bhai.city),
CustomRowText("State", bhai.state),
],
),
),
),
]),
),
]);
}
pw.Row CustomRowText(String label, String data) {
return pw.Row(children: [
pw.Expanded(
flex: 2,
child: pw.Text(label,
style: pw.TextStyle(fontWeight: pw.FontWeight.bold))),
pw.Expanded(flex: 7, child: pw.Text(data))
]);
}
i used image_picker package in my app and it works fine for one image but now i want to use it for multiple images and store them in an array as File. any idea could be greate.
Add dependecy of image_picker:
image_picker: ^0.8.4+3
Then make a method for selectImages():
final ImagePicker imagePicker = ImagePicker();
List<XFile>? imageFileList = [];
void selectImages() async {
final List<XFile>? selectedImages = await
imagePicker.pickMultiImage();
if (selectedImages!.isNotEmpty) {
imageFileList!.addAll(selectedImages);
}
print("Image List Length:" + imageFileList!.length.toString());
setState((){});
}
Create a builder for showing selected Images:
return Scaffold(
appBar: AppBar(
title: Text('Multiple Images'),
),
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: () {
selectImages();
},
child: Text('Select Images'),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
itemCount: imageFileList!.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return Image.file(File(imageFileList![index].path),
fit: BoxFit.cover,);
}),
),
),
],
),
));
Complete Source code available in github link...
https://github.com/NishaJain24/multi_image_picker
you should use this
//add this to pubspec.yaml
multi_image_picker: ^4.7.14
//add those to the dart file
import 'package:flutter/material.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'dart:async';
//add a button then in onPressed do this
MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
materialOptions: MaterialOptions(
actionBarTitle: "FlutterCorner.com",
),
);
for further infos check this
https://medium.com/#fluttercorner/how-to-select-multiple-images-with-flutter-8fe8e4c78d08
The documentation covers that in here .
final List<XFile>? images = await _picker.pickMultiImage(source: ImageSource.gallery);
That saves it in a list of XFile. There are some platform specific implementation you have to go through so dont miss that. Just have a look at the documentation.
I have a PDF file and I would like to reproduce a page curl effect like in this package page:
https://pub.flutter-io.cn/packages/page_turn
I tried using this page_turn plugin and it takes list of widgets that will display in order. I tried using native_pdf_renderer plugin to render the pdf and display on each page, but when I do this, the pages are blank. but if I remove from the PageTurn widget, it works.
import 'package:flutter/material.dart';
import 'package:native_pdf_renderer/native_pdf_renderer.dart';
import 'package:page_turn/page_turn.dart';
class TestScreen extends StatelessWidget {
final _controller = GlobalKey<PageTurnState>();
Future<PdfPageImage> getPageImage() async {
final document = await PdfDocument.openAsset('assets/pdfs/222.pdf');
final page = await document.getPage(6);
final pageImage = await page.render(
width: page.width,
height: page.height,
format: PdfPageFormat.JPEG,
);
await page.close();
return pageImage;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: FutureBuilder<PdfPageImage>(
future: getPageImage(),
builder: (context, snapshot) {
print(snapshot.data);
if (snapshot.data == null) return CircularProgressIndicator();
// This works:
// return Image(
// image: MemoryImage(snapshot.data.bytes),
// );
//This makes all my pages blank
return PageTurn(
key: _controller,
backgroundColor: Colors.white,
children: <Widget>[
Image(
image: MemoryImage(snapshot.data.bytes),
),
Image(
image: MemoryImage(snapshot.data.bytes),
),
Image(
image: MemoryImage(snapshot.data.bytes),
),
],
);
},
)),
);
}
}
after reading the lib code i see there is widget to show image pre-renderd
you should use PageTurnImage instead Image like this
PageTurn(
key: _controller,
backgroundColor: Colors.white,
children: <Widget>[
PageTurnImage(
image: MemoryImage(snapshot.data.bytes),
),
PageTurnImage(
image: MemoryImage(snapshot.data.bytes),
),
PageTurnImage(
image: MemoryImage(snapshot.data.bytes),
),
],
);
try it and give me a feedback and up vote if it work
There does not appear to be any pub.dev plugin that allows sharing of PDF files.
My app creates PDFs.. I want to be able to share these PDFs.
So far, it seems that all these plugins only support sharing of PNG's..
How should I share my PDF?
I've used package esys_flutter_share
var sharePdf = await file.readAsBytes();
await Share.file(
'PDF Document',
'project.pdf',
sharePdf.buffer.asUint8List(),
'*/*',
);
I finally achieved it by using the below package as esys_flutter_share no null safety.
path_provider: ^2.0.12
share_plus: ^6.3.1
screenshot: ^1.3.0
First creating the function==> widget to pdf
class _MyGoalDetailsState extends State<MyGoalDetails> {
List<GlobalKey> printKey = List<GlobalKey>.generate(100, (index) => GlobalKey(debugLabel: 'key_$index'),growable: false);
final doc = pw.Document();
// ========== Funtion() for widget to pdf ============
void _printScreen(int index) async {
final image = await WidgetWraper.fromKey(
key: printKey[index],
pixelRatio: 2.0,
);
final directory = await getTemporaryDirectory();
final file = File('${directory.path}/my_goal.pdf');
final pdf = pw.Document();
pdf.addPage(pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
);
},
));
await file.writeAsBytes(await pdf.save());
await Share.shareFiles(
[file.path],
text: 'Check out my goal details',
subject: 'My goal details',
);
}
......................................
...................
Then wrap the widget which I want to pdf.
RepaintBoundary(
key: printKey[0],
child: Container(
color: Colors.white,
padding: const EdgeInsets.fromLTRB(15,15,15,0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [.................................
And onPress of my share button creating my pdf..
IconButton(
onPressed: () async {
_printScreen(0);
},
icon: const Icon(Icons.share),
),