Flutter, mobil uygulama geliştirme dünyasında hızla popüler hale gelen bir frameworktür. Çapraz platform desteği ve güçlü widget yapısıyla geliştiricilere birçok kolaylık sağlamaktadır. Bu yazıda, Flutter ile PDF dosyaları oluşturmanın temel adımlarını inceleyeceğiz. Özellikle, syncfusion_flutter_pdf paketini kullanarak PDF oluşturma, içerisine metin ekleme ve çıktı alma gibi işlemleri ele alacağız. Ayrıca, sayfa ekleme, metin ekleme, linkler oluşturma, tablolar ekleme gibi ileri düzey konuları da kapsayacağız.
Giriş
PDF dosyaları, evrensel olarak kullanılan ve dökümanların sabit bir biçimde görüntülenmesini sağlayan dosya formatlarıdır. İş dünyasından eğitim sektörüne kadar birçok alanda kullanılırlar. Flutter uygulamalarında PDF oluşturma ve düzenleme gereksinimleri oldukça yaygındır. Bu yazıda, syncfusion_flutter_pdf paketini kullanarak nasıl PDF oluşturabileceğinizi öğreneceksiniz.
Gerekli Paketlerin Kurulumu
PDF işlemleri için kullanacağımız syncfusion_flutter_pdf paketini projemize eklememiz gerekmektedir. Bu makalenin oluşturulduğu tarihteki paketlerin son versiyonları kullanılmıştır. Daha güncel sürümleri kullanabilmek adına makaleyi okuduğunuz tarihteki versiyonlarını kullanmanızı tavsiye ederim. Bunun için pubspec.yaml dosyanıza aşağıdaki satırı ekleyin:
dependencies:
flutter:
sdk: flutter
syncfusion_flutter_pdf: ^26.1.39
open_file: ^3.3.2
path_provider: ^2.1.3
Ardından terminal üzerinden pub get komutunu çalıştırarak paketlerin indirilmesini sağlayın.
flutter pub get
Syncfusion_flutter_pdf ile PDF Oluşturma
İlk adım olarak, PDF dosyasını oluşturmak ve temel ayarlarını yapmakla başlayacağız. Aşağıdaki kod parçası, yeni bir PDF belgesi oluşturur ve bir sayfa ekler.
import 'package:syncfusion_flutter_pdf/pdf.dart';
Future<void> createPdf() async {
// Yeni bir PDF belgesi oluştur
final PdfDocument document = PdfDocument();
// İlk sayfayı ekle
document.pages.add();
// PDF belgesini kaydet ve görüntüle
List<int> bytes = document.save();
document.dispose();
// Byte verisini dosyaya yaz ve cihazda aç (uygulama özel bir metod gerektirir)
saveAndLaunchFile(bytes, 'Output.pdf');
}
PDF’e Metin Ekleme
PDF’e metin eklemek için PdfTextElement sınıfını kullanacağız. Aşağıdaki örnekte, bir sayfaya başlık ve alt başlık eklenmektedir.
void addTextToPdf(PdfDocument document) {
final page = document.pages[0];
// Başlık
final title = PdfTextElement(
text: 'Flutter ile PDF Oluşturma',
font: PdfStandardFont(PdfFontFamily.helvetica, 30),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
// Alt başlık
final subtitle = PdfTextElement(
text: 'Syncfusion_flutter_pdf Kullanımı',
font: PdfStandardFont(PdfFontFamily.helvetica, 20),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
// Metni sayfaya ekle
title.draw(page: page, bounds: Rect.fromLTWH(0, 0, 500, 50));
subtitle.draw(page: page, bounds: Rect.fromLTWH(0, 40, 500, 50));
}
PDF Çıktısı Alma
Oluşturulan PDF dosyasını cihazda saklamak ve görüntülemek için özel metodlar kullanabilirsiniz. Aşağıdaki örnek, dosyayı kaydetmek ve cihazda açmak için bir yardımcı metot içermektedir. Ayrıca oluşturulan dosyayı açabilmek için open_file paketinin kullanıldığına dikkat etmemiz gerekir.
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:open_file/open_file.dart';
Future<void> saveAndLaunchFile(List<int> bytes, String fileName) async {
final path = (await getExternalStorageDirectory())!.path;
final file = File('$path/$fileName');
await file.writeAsBytes(bytes, flush: true);
OpenFile.open('$path/$fileName');
}
Sayfa Yönetimi
Sayfa Ekleme
PDF belgesine birden fazla sayfa eklemek mümkündür. Aşağıdaki örnek, bir PDF belgesine iki sayfa ekler.
void addPagesToPdf(PdfDocument document) {
// İlk sayfa
document.pages.add();
// İkinci sayfa
document.pages.add();
}
Sayfa Numaralandırma
PDF belgesinde sayfa numaraları eklemek, belgelerin daha düzenli ve okunabilir olmasını sağlar. Aşağıdaki örnekte, her sayfanın alt kısmına sayfa numarası eklenir.
void addPageNumbers(PdfDocument document) {
final PdfPageTemplateElement footer = PdfPageTemplateElement(
Rect.fromLTWH(0, 0, document.pageSettings.size.width, 50));
final PdfPageNumberField pageNumber = PdfPageNumberField(
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)));
pageNumber.numberStyle = PdfNumberStyle.numeric;
final PdfCompositeField compositeField = PdfCompositeField(
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
text: 'Page {0} of {1}',
fields: <PdfAutomaticField>[pageNumber, PdfPageCountField()]);
compositeField.bounds = footer.bounds;
footer.graphics.drawString(compositeField.text,
PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
bounds: footer.bounds,
format: PdfStringFormat(alignment: PdfTextAlignment.center));
document.template.bottom = footer;
}
Metin Ekleme ve Özelleştirme
Başlık ve Alt Başlık Ekleme
PDF belgelerinde başlık ve alt başlık eklemek oldukça yaygındır. Aşağıdaki örnek, sayfaya başlık ve alt başlık eklemektedir.
void addHeadingAndSubheading(PdfDocument document) {
final PdfPage page = document.pages[0];
// Başlık
final PdfTextElement heading = PdfTextElement(
text: 'Flutter ile PDF Oluşturma',
font: PdfStandardFont(PdfFontFamily.helvetica, 30),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
// Alt başlık
final PdfTextElement subheading = PdfTextElement(
text: 'Syncfusion_flutter_pdf Kullanımı',
font: PdfStandardFont(PdfFontFamily.helvetica, 20),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
heading.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, 50));
subheading.draw(page: page, bounds: Rect.fromLTWH(0, 50, page.getClientSize().width, 50));
}
Paragraf Ekleme
PDF belgesine uzun metinler eklemek için paragraflar kullanılabilir. Aşağıdaki örnek, bir sayfaya paragraf ekler.
void addParagraph(PdfDocument document) {
final PdfPage page = document.pages[0];
final PdfTextElement paragraph = PdfTextElement(
text: 'Flutter, Google tarafından geliştirilen açık kaynaklı bir UI yazılım geliştirme kitidir (SDK). '
'Flutter, tek bir kod tabanı kullanarak Android, iOS, Linux, macOS, Windows, Google Fuchsia '
've web için neredeyse yerel uygulamalar oluşturmanıza olanak tanır.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
paragraph.draw(page: page, bounds: Rect.fromLTWH(0, 100, page.getClientSize().width, page.getClientSize().height - 100));
}
Yazı Tipi ve Stil Ayarları
PDF belgesinde metinleri daha okunabilir ve estetik hale getirmek için yazı tipi ve stil ayarları kullanılabilir.
void addStyledText(PdfDocument document) {
final PdfPage page = document.pages[0];
// Kalın metin
final PdfTextElement boldText = PdfTextElement(
text: 'Bu metin kalındır.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
// İtalik metin
final PdfTextElement italicText = PdfTextElement(
text: 'Bu metin italiktir.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.italic),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
// Altı çizili metin
final PdfTextElement underlineText = PdfTextElement(
text: 'Bu metnin altı çizilidir.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.underline),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
boldText.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, 50));
italicText.draw(page: page, bounds: Rect.fromLTWH(0, 50, page.getClientSize().width, 50));
underlineText.draw(page: page, bounds: Rect.fromLTWH(0, 100, page.getClientSize().width, 50));
}
Görseller ve Grafikler
Görsel Ekleme
PDF belgesine görsel eklemek için PdfBitmap sınıfını kullanabiliriz.
void addImageToPdf(PdfDocument document) {
final PdfPage page = document.pages.add();
final ByteData data = await rootBundle.load('assets/flutter_logo.png');
final Uint8List bytes = data.buffer.asUint8List();
final PdfBitmap image = PdfBitmap(bytes);
page.graphics.drawImage(image, Rect.fromLTWH(0, 0, 200, 200));
}
Grafikler ve Şemalar
PDF belgesine grafik veya şema eklemek için PdfGraphics sınıfını kullanabiliriz.
void addChartToPdf(PdfDocument document) {
final PdfPage page = document.pages.add();
page.graphics.drawRectangle(
bounds: Rect.fromLTWH(0, 0, 100, 100),
pen: PdfPen(PdfColor(255, 0, 0), width: 2),
brush: PdfSolidBrush(PdfColor(255, 0, 0)),
);
page.graphics.drawEllipse(
bounds: Rect.fromLTWH(150, 0, 100, 100),
pen: PdfPen(PdfColor(0, 255, 0), width: 2),
brush: PdfSolidBrush(PdfColor(0, 255, 0)),
);
}
Tablolar ve Listeler
Basit Tablolar
PDF belgesine basit tablolar eklemek için PdfGrid sınıfını kullanabiliriz.
void addSimpleTable(PdfDocument document) {
final PdfPage page = document.pages.add();
final PdfGrid grid = PdfGrid();
grid.columns.add(count: 3);
final PdfGridRow header = grid.headers.add(1)[0];
header.cells[0].value = 'ID';
header.cells[1].value = 'Name';
header.cells[2].value = 'Age';
final PdfGridRow row1 = grid.rows.add();
row1.cells[0].value = '1';
row1.cells[1].value = 'John Doe';
row1.cells[2].value = ‘30’;
final PdfGridRow row2 = grid.rows.add();
row2.cells[0].value = ‘2’;
row2.cells[1].value = ‘Jane Smith’;
row2.cells[2].value = ‘25’;
grid.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, page.getClientSize().height));
}
Dinamik olarak veri eklenen tablolar oluşturmak için de `PdfGrid` kullanılabilir.
void addDynamicTable(PdfDocument document) {
final PdfPage page = document.pages.add();
final PdfGrid grid = PdfGrid();
grid.columns.add(count: 3);
final PdfGridRow header = grid.headers.add(1)[0];
header.cells[0].value = 'ID';
header.cells[1].value = 'Name';
header.cells[2].value = 'Age';
final List<Map<String, String>> data = [
{'ID': '1', 'Name': 'John Doe', 'Age': '30'},
{'ID': '2', 'Name': 'Jane Smith', 'Age': '25'},
{'ID': '3', 'Name': 'Sam Brown', 'Age': '20'},
];
for (final item in data) {
final PdfGridRow row = grid.rows.add();
row.cells[0].value = item['ID'];
row.cells[1].value = item['Name'];
row.cells[2].value = item['Age'];
}
grid.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, page.getClientSize().height));
}
Listeler ve Madde İşaretleri
PDF belgesine listeler ve madde işaretleri eklemek için PdfOrderedList ve PdfUnorderedList sınıflarını kullanabiliriz.
void addListsToPdf(PdfDocument document) {
final PdfPage page = document.pages.add();
final PdfOrderedList orderedList = PdfOrderedList(
items: ['Birinci madde', 'İkinci madde', 'Üçüncü madde'],
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
orderedList.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, page.getClientSize().height));
final PdfUnorderedList unorderedList = PdfUnorderedList(
items: ['İlk madde', 'İkinci madde', 'Üçüncü madde'],
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
unorderedList.draw(page: page, bounds: Rect.fromLTWH(0, 100, page.getClientSize().width, page.getClientSize().height));
}
Örnek Uygulama
Tam anlamıyla bir PDF oluşturma sürecini görebilmeniz için detaylı bir örnek sunacağız. Bu örnek, bir PDF oluşturur, içerisine başlık, metin, tablo, resim ve link ekler ve sonunda dosyayı cihazda kaydeder ve açar.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:open_file/open_file.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter PDF Oluşturma')),
body: Center(
child: ElevatedButton(
onPressed: createPdf,
child: Text('PDF Oluştur'),
),
),
),
);
}
Future<void> createPdf() async {
final PdfDocument document = PdfDocument();
final PdfPage page = document.pages.add();
// Başlık
final PdfTextElement heading = PdfTextElement(
text: 'Flutter ile PDF Oluşturma',
font: PdfStandardFont(PdfFontFamily.helvetica, 30),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
heading.draw(page: page, bounds: Rect.fromLTWH(0, 0, page.getClientSize().width, 50));
// Alt başlık
final PdfTextElement subheading = PdfTextElement(
text: 'Syncfusion_flutter_pdf Kullanımı',
font: PdfStandardFont(PdfFontFamily.helvetica, 20),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
subheading.draw(page: page, bounds: Rect.fromLTWH(0, 50, page.getClientSize().width, 50));
// Paragraf
final PdfTextElement paragraph = PdfTextElement(
text: 'Flutter, Google tarafından geliştirilen açık kaynaklı bir UI yazılım geliştirme kitidir (SDK). '
'Flutter, tek bir kod tabanı kullanarak Android, iOS, Linux, macOS, Windows, Google Fuchsia '
've web için neredeyse yerel uygulamalar oluşturmanıza olanak tanır.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
);
paragraph.draw(page: page, bounds: Rect.fromLTWH(0, 100, page.getClientSize().width, page.getClientSize().height - 100));
// Tablo
final PdfGrid grid = PdfGrid();
grid.columns.add(count: 3);
final PdfGridRow header = grid.headers.add(1)[0];
header.cells[0].value = 'ID';
header.cells[1].value = 'Name';
header.cells[2].value = 'Age';
final List<Map<String, String>> data = [
{'ID': '1', 'Name': 'John Doe', 'Age': '30'},
{'ID': '2', 'Name': 'Jane Smith', 'Age': '25'},
{'ID': '3', 'Name': 'Sam Brown', 'Age': '20'},
];
for (final item in data) {
final PdfGridRow row = grid.rows.add();
row.cells[0].value = item['ID'];
row.cells[1].value = item['Name'];
row.cells[2].value = item['Age'];
}
grid.draw(page: page, bounds: Rect.fromLTWH(0, 200, page.getClientSize().width, page.getClientSize().height));
// Resim
final ByteData data = await rootBundle.load('assets/flutter_logo.png');
final Uint8List bytes = data.buffer.asUint8List();
final PdfBitmap image = PdfBitmap(bytes);
page.graphics.drawImage(image, Rect.fromLTWH(0, 300, 200, 200));
// İç link
final PdfDestination destination = PdfDestination(page, Offset(0, 0));
final PdfTextWebLink link = PdfTextWebLink(
text: 'En üste gitmek için tıklayın.',
font: PdfStandardFont(PdfFontFamily.helvetica, 12),
brush: PdfSolidBrush(PdfColor(0, 0, 0)),
url: destination,
);
link.draw(page: page, bounds: Rect.fromLTWH(0, 500, page.getClientSize().width, 50));
// PDF belgesini kaydet ve görüntüle
List<int> bytes = document.save();
document.dispose();
await saveAndLaunchFile(bytes, 'Output.pdf');
}
Future<void> saveAndLaunchFile(List<int> bytes, String fileName) async {
final path = (await getExternalStorageDirectory())!.path;
final file = File('$path/$fileName');
await file.writeAsBytes(bytes, flush: true);
OpenFile.open('$path/$fileName');
}
}
Bu örnek uygulamada, bir butona basıldığında PDF dosyası oluşturulmakta ve cihazda görüntülenmektedir.
10. Sonuç
Bu makalede, Flutter ile PDF oluşturma sürecini ve syncfusion_flutter_pdf paketini kullanarak nasıl temel PDF işlemleri yapabileceğinizi öğrendik. Ayrıca, PDF belgesine metin, link, tablo, resim ve daha fazlasını nasıl ekleyebileceğinizi inceledik. Flutter’ın güçlü yetenekleri sayesinde mobil uygulamalarda PDF oluşturma işlemleri oldukça kolay ve etkili bir şekilde gerçekleştirilebilir. Bu bilgilerle, kendi projelerinizde PDF işlemlerini rahatlıkla uygulayabilirsiniz. Esenlikler Dilerim.