관리 메뉴

Bull

[Flutter::package] "pdf" package review 하기 본문

Software Framework/Flutter

[Flutter::package] "pdf" package review 하기

Bull_ 2024. 8. 21. 03:06

https://pub.dev/packages/pdf

 

pdf | Dart package

A pdf producer for Dart. It can create pdf files for both web or flutter.

pub.dev

pdf package

플러터에서 pdf 를 추출하고싶을 때 사용한다. pdf 자체를 만드는 건 아래 사진과 같이 여러 플랫폼에서 지원 가능하다.

모든 플랫폼 가능

pdf를 추출하거나 보려면 priniting 패키지를 같이 사용한다. 혹은 pdf view/extract 가 가능한 패키지로 볼 수 있다. pdf 패키지 만으로도 추출할 수 있지만 간단함을 위해 나는 printing 패키지를 함께 쓰겠다. pdf 패키지로 추출하는 방법은 패키지에 나와있지만 보여주자면 아래를 참고하면 된다.

final file = File("example.pdf");
await file.writeAsBytes(await pdf.save());
# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  pdf: ^3.11.1
  printing: ^5.13.2

CODE

import 'package:flutter/material.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          backgroundColor: Colors.white,
          title: Text('PDF Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _createPdf,
            child: Text('Generate PDF',
                style: TextStyle(fontSize: 16, color: Colors.black)),
            style: ElevatedButton.styleFrom(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15),
              ),
              elevation: 5,
              padding: EdgeInsets.all(20),
              backgroundColor: Colors.amber,
            ),
          ),
        ),
      ),
    );
  }

  Future<void> _createPdf() async {
    final pdf = pw.Document();
    final netImage1 = await networkImage(
        'https://images.unsplash.com/photo-1584395630827-860eee694d7b');
    final netImage2 = await networkImage(
        'https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0');
    final netImage3 = await networkImage(
        'https://images.unsplash.com/photo-1516117172878-fd2c41f4a759');

    pdf.addPage(
      pw.Page(
        build: (pw.Context context) {
          return pw.Center(
            child: pw.Image(netImage1, width: 200, height: 150),
          );
        },
      ),
    );
    pdf.addPage(
      pw.Page(
        build: (pw.Context context) {
          return pw.Center(
            child: pw.Image(netImage2, width: 200, height: 150),
          );
        },
      ),
    );
    pdf.addPage(
      pw.Page(
        build: (pw.Context context) {
          return pw.Center(
            child: pw.Image(netImage3, width: 200, height: 150),
          );
        },
      ),
    );
    pdf.addPage(
      pw.Page(
        build: (pw.Context context) {
          return pw.Center(
            child: pw.Container(
              alignment: pw.Alignment.center,
              color: PdfColors.grey300,
              padding: const pw.EdgeInsets.all(10),
              child: pw.Text(
                'This is a centered text box',
                style: pw.TextStyle(fontSize: 20, color: PdfColors.black),
              ),
            ),
          );
        },
      ),
    );

    // PDF 미리보기 및 저장
    await Printing.layoutPdf(
        onLayout: (PdfPageFormat format) async => pdf.save());
  }
}

pw 알리야스를 통해 pw.Document() 인스턴스를 만들었다.

 

pdf.addPage : pdf의 페이지를 추가한다.

 

networkImage : printing 패키지의 메소드이다. 다른 방법을 찾아보진 않았으나, pw.Image의 첫 인자에 이미지 파일은 ImageProvider 를 반환해야 하는데 외부에서 ImageProvider 클래스인 이미지를 가져오려면 networkImage 메소드를 통해 구현가능하다.

 

pw.Center : 플러터 위젯의 Center와 동일한 효과를 낸다. pdf 자체를 플러터 위젯트리구조로 적용한듯보인다.

 

pw.Context : 빌드 Context도 pw를 통해 사용된다.

 

pw.Alignment : 이쯤되면 눈치챘겠지만 pw에 적용할 위젯은 pw.(기존위젯) 방식을 사용한다.

수 많은 프로퍼티가 존재하니 필요한 거 찾아서 쓰면 된다.

 

Printing.layoutPdf : 미리보기를 지원한다.

- onLayout 프로퍼티는 Type: FutureOr<Uint8List> Function(PdfPageFormat) 타입을 등록하면된다.

pdf.save 동일하게 32비트 부호없는 정수형 바이트 배열을 반환하기 때문에 가능하다. 파일 처리할 때 유용하게 쓰이는 타입이다. Printing 패키지를 통해서 결과 화면과 같이 편한한 UI로 기능을 쓸 수 있다.