docs_auto_sign 0.0.2 copy "docs_auto_sign: ^0.0.2" to clipboard
docs_auto_sign: ^0.0.2 copied to clipboard

Automatically detect signature fields in a PDF and stamp a PNG signature image onto them.

example/lib/main.dart

import 'dart:typed_data';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:signature/signature.dart';
import 'package:docs_auto_sign/docs_auto_sign.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Docs Auto Sign Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  File? _pdfFile;
  Uint8List? _signatureBytes;
  AutoSignResult? _result;
  bool _isSigning = false;

  final SignatureController _signatureController = SignatureController(
    penStrokeWidth: 2,
    penColor: Colors.black,
    exportBackgroundColor: Colors.white,
  );

  @override
  void dispose() {
    _signatureController.dispose();
    super.dispose();
  }

  // Step 1: PDF pick করো
  Future<void> _pickPdf() async {
    final result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['pdf'],
    );
    if (result != null && result.files.single.path != null) {
      setState(() {
        _pdfFile = File(result.files.single.path!);
        _result = null;
      });
    }
  }

  // Step 2: Signature confirm করো
  Future<void> _confirmSignature() async {
    if (_signatureController.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Please draw your signature first!')),
      );
      return;
    }
    final bytes = await _signatureController.toPngBytes(
      width: 400,
      height: 200,
    );
    if (bytes != null) {
      setState(() => _signatureBytes = bytes);
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Signature saved! ✅'),
          backgroundColor: Colors.green,
        ),
      );
    }
  }

  // Step 3: Sign করো
  Future<void> _signDocument() async {
    if (_pdfFile == null || _signatureBytes == null) return;

    setState(() => _isSigning = true);

    try {
      final result = await AutoSignService.applySignatureToPdf(
        originalPdfFile: _pdfFile!,
        signatureBytes: _signatureBytes!,
        targetWords: ['signature', 'sign'],
      );

      // Signed PDF save করো
      final dir = await getTemporaryDirectory();
      final outFile = File('${dir.path}/signed_output.pdf');
      await outFile.writeAsBytes(result.signedPdfBytes);

      setState(() {
        _result = result;
        _isSigning = false;
      });
    } catch (e) {
      setState(() => _isSigning = false);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: $e'), backgroundColor: Colors.red),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Docs Auto Sign Example'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [

            // ── Step 1: PDF Pick ─────────────────────────────────────────
            const Text('Step 1: Pick a PDF',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            const SizedBox(height: 8),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton.icon(
                onPressed: _pickPdf,
                icon: const Icon(Icons.upload_file),
                label: const Text('Pick PDF'),
              ),
            ),
            if (_pdfFile != null) ...[
              const SizedBox(height: 8),
              Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: Colors.green[50],
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(color: Colors.green),
                ),
                child: Row(
                  children: [
                    const Icon(Icons.check_circle, color: Colors.green),
                    const SizedBox(width: 8),
                    Expanded(
                      child: Text(
                        _pdfFile!.path.split('/').last,
                        style: const TextStyle(fontSize: 13),
                      ),
                    ),
                  ],
                ),
              ),
            ],

            const SizedBox(height: 24),

            // ── Step 2: Draw Signature ───────────────────────────────────
            const Text('Step 2: Draw Signature',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            const SizedBox(height: 8),
            Container(
              height: 200,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: BorderRadius.circular(12),
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(12),
                child: Signature(
                  controller: _signatureController,
                  backgroundColor: Colors.white,
                ),
              ),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: OutlinedButton.icon(
                    onPressed: () => _signatureController.clear(),
                    icon: const Icon(Icons.clear),
                    label: const Text('Clear'),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _confirmSignature,
                    icon: const Icon(Icons.check),
                    label: const Text('Confirm'),
                  ),
                ),
              ],
            ),
            if (_signatureBytes != null) ...[
              const SizedBox(height: 8),
              Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: Colors.green[50],
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(color: Colors.green),
                ),
                child: const Row(
                  children: [
                    Icon(Icons.check_circle, color: Colors.green),
                    SizedBox(width: 8),
                    Text('Signature ready! ✅'),
                  ],
                ),
              ),
            ],

            const SizedBox(height: 24),

            // ── Step 3: Sign Document ────────────────────────────────────
            const Text('Step 3: Sign Document',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            const SizedBox(height: 8),
            SizedBox(
              width: double.infinity,
              height: 52,
              child: ElevatedButton.icon(
                onPressed: (_pdfFile != null &&
                    _signatureBytes != null &&
                    !_isSigning)
                    ? _signDocument
                    : null,
                icon: _isSigning
                    ? const SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(strokeWidth: 2),
                )
                    : const Icon(Icons.draw),
                label: Text(_isSigning ? 'Signing...' : 'Sign Document'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.indigo,
                  foregroundColor: Colors.white,
                ),
              ),
            ),

            // ── Result ───────────────────────────────────────────────────
            if (_result != null) ...[
              const SizedBox(height: 24),
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.indigo[50],
                  borderRadius: BorderRadius.circular(12),
                  border: Border.all(color: Colors.indigo),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Row(
                      children: [
                        Icon(Icons.check_circle, color: Colors.indigo),
                        SizedBox(width: 8),
                        Text('Document Signed Successfully! 🎉',
                            style: TextStyle(
                                fontWeight: FontWeight.bold,
                                color: Colors.indigo)),
                      ],
                    ),
                    const SizedBox(height: 8),
                    Text(
                        'Total signatures added: ${_result!.totalSignaturesAdded}'),
                    Text('Pages modified: ${_result!.pagesModified}'),
                  ],
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }
}
4
likes
140
points
53
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Automatically detect signature fields in a PDF and stamp a PNG signature image onto them.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, syncfusion_flutter_pdf

More

Packages that depend on docs_auto_sign