create-pdf-using-flutter

Flutter ve Syncfusion ile PDF Oluşturma

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.

Leave a Comment

Your email address will not be published. Required fields are marked *