Tuesday, 24 September 2019

Icons not rendering in PDF when creating views using HTML, CSS in Flutter app. How to use font-awesome library in Flutter-app locally?

I am using HTML/CSS to render PDF views. So, I need render font-awesome-icons in that PDF (online as well as offline by putting font-awesome files in asset folder).

Note: When using online, Icons are not rendering in Flutter-android-app however it is rendering in Flutter-iOS-app.

return '<link rel="stylesheet" type="text/css" href=https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css>';

iOS-Screenshot:

enter image description here

Android-Screenshot: Most of the case the icons do not renders. (Note: Rarely out of 100 times it renders 3 times)

enter image description here

Can we use font-awesome library in Flutter(android-iOS) locally by putting the font-awesome files under assets folder like Using Web Fonts with CSS ? If it is possible how? Please assist me I am waiting for the reply.

Full Source Code:

RenderHtml.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_cv_builder/playground/features/resume/pdf_utils/viewer/viewer.dart';

import 'package:pdf/pdf.dart';
import 'package:path_provider/path_provider.dart';
import 'package:printing/printing.dart';

import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

class RenderHtml {
  // String font_awesome_css = "";

  PdfPageFormat format2 = PdfPageFormat.a4.copyWith(
      height: PdfPageFormat.a4.height,
      width: PdfPageFormat.a4.width,
      marginBottom: 0,
      marginLeft: 0,
      marginRight: 0,
      marginTop: 0);

  Future<void> printPdf() async {
    print('Print ...');
    await Printing.layoutPdf(onLayout: (PdfPageFormat format) async {
      return await Printing.convertHtml(
          format: format2,
          html: '<!DOCTYPE html><html><head><meta charset="UTF-8">' +
              getRatingbarCss() +
              '<style>.checked {color: red;}</style>' +
              '</head><body style="margin:0;padding:0" bgcolor="white">' +
              makeProfileImage() +
              '<h2 style="color:black;">Star Rating</h2><span class="fa fa-star checked"/><span class="fa fa-star checked"/><span class="fa fa-star checked"/><span class="fa fa-star"/><span class="fa fa-star"/></body></html>');
    });
  }

  String htmlString = "";
  RenderHtml() {
    htmlString = '<html>' +
        getHead() +
        '<body bgcolor="#E6E6FA"><table><tr><td><br><br><h5><b>Internationalization:</b> 中國哲學書電子化計劃 महात्मा गांधी ने कहा الصفحة الرئيسية 안녕하세요! 저는 대니라고 해요.    昨夜のコンサートは最高でした。</h5><br><br>' +
        makeRatingOld() +
        newCssLinkRel() +
        makeRating() +
        makeIcons() +
        testIcon() +
        makeHorizontalProgress() +
        makeHorizontalProgress2() +
        makeHorizontalProgress3() +
        makeProfileImage() +
        makeCard() +
        makeCircularProgressbar() +
        '</td></tr></table><div><div id="header_set"><br><br><h2> HTML Table SPLIT</h2> ' +
        makeTableSplitTest() +
        '</body></html>';
  }

  Future<void> saveAsFileHTML(BuildContext context) async {
    final Directory appDocDir = await getApplicationDocumentsDirectory();
    final String appDocPath = appDocDir.path;
    final File file = File(appDocPath + '/' + 'document.pdf');
    print('Save as file ${file.path} ...');

    // font_awesome_css = await loadAsset();
    // print("******************************\n\n" +
    //     font_awesome_css +
    //     "\n\n******************************");

    await file.writeAsBytes(
        (await Printing.convertHtml(format: format2, html: htmlString)));

    Navigator.push<dynamic>(
      context,
      MaterialPageRoute<dynamic>(
          builder: (BuildContext context) => PdfViewer(file: file)),
    );
  }

  getHead() {
    // default and dynamic font color layout-bg
    return '<head><meta name="viewport" content="width=device-width, initial-scale=1">' +
        getProgressbarCss() +
        getNewCeesRel() +
        getRatingbarCss() +
        '<style>' +
        // font_awesome_css +
        getRatingStyle() +
        makeProgressStyle() +
        testIconLinkRel() +
        '</style></head>';
  }

  getLayoutMargin() {
    return "";
  }

  Future<String> loadAsset() async {
    return await rootBundle.loadString('assets/css/font-awesome.min.css');
  }

  makeIcons() {
    return '<br><br><h2>Make Icons Font Awesome<h2><br><i class="fa fa-car"></i> <i class="fa fa-car" style="font-size:48px;"></i> <i class="fa fa-car" style="font-size:60px;color:red;"></i><br>';
  }

  makeRatingOld() {
    return '<h2>Square Rating</h2> <span class="fa fa-square checked"></span> <span class="fa fa-square checked"></span> <span class="fa fa-square checked"></span> <span class="fa fa-square"></span> <span class="fa fa-square"></span><br><br><h2>Circular Rating</h2> <span class="fa fa-circle checked"></span> <span class="fa fa-circle checked"></span> <span class="fa fa-circle checked"></span> <span class="fa fa-circle"></span> <span class="fa fa-circle"></span><br><br><h2>Star Rating</h2><span class="fa fa-star checked"></span><span class="fa fa-star checked"></span><span class="fa fa-star checked"></span><span class="fa fa-star"></span><span class="fa fa-star"></span><br><br> ';
  }

  getProgressbarCss() {
    // return '<link rel="stylesheet" type="text/css" href=https://www.w3schools.com/w3css/4/w3.css>';
    return '<link rel="stylesheet" type="text/css" href=file:///android_asset/flutter_assets/assets/css/w3.css>';
  }

  getRatingbarCss() {
    return '<link rel="stylesheet" type="text/css" href=https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css>';
    // return '<link rel="stylesheet" type="text/css" href=https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css>';
    // return '<link rel="stylesheet" type="text/css" href=file:///android_asset/flutter_assets/assets/css/font-awesome.min.css>';
    // return "";
  }

  makeRating() {
    return '<h2>New Rating</h2> <div class="rate"><input type="radio" id="star5" name="rate" value="5"/><label for="star5" title="text">5 stars</label><input type="radio" id="star4" name="rate" value="4" checked/><label for="star4" title="text">4 stars</label><input type="radio" id="star3" name="rate" value="3"/><label for="star3" title="text">3 stars</label><input type="radio" id="star2" name="rate" value="2"/><label for="star2" title="text">2 stars</label><input type="radio" id="star1" name="rate" value="1"/><label for="star1" title="text">1 star</label></div><br>';
  }

  getRatingStyle() {
    // ⬤  █ ■
    return "*{ margin: 0; padding: 0; } .rate { float: left; height: 46px; padding: 0 10px; } .rate:not(:checked) > input { position:absolute; top:-9999px; } .rate:not(:checked) > label { float:right; width:1em; overflow:hidden; white-space:nowrap; cursor:pointer; font-size:20px; color:#ccc; } .rate:not(:checked) > label:before { content: '⬤ '; } .rate > input:checked ~ label { color: #ff0000; } .rate:not(:checked) > label:hover, .rate:not(:checked) > label:hover ~ label { color: #de1717; } .rate > input:checked + label:hover, .rate > input:checked + label:hover ~ label, .rate > input:checked ~ label:hover, .rate > input:checked ~ label:hover ~ label, .rate > label:hover ~ input:checked ~ label { color: #c50808; }";
  }

  makeProfileImage() {
    return '<img src="https://i.ytimg.com/vi/RHLknisJ-Sg/maxresdefault.jpg" alt="Avatar" height="200" width="200" style="border-radius: 50%;">';
    // return '<img src="file:///android_asset/flutter_assets/assets/profyl.jpg" alt="Avatar" height="200" width="200" style="border-radius: 50%;">';
    // return '<img src="/flutter_assets/assets/profyl.jpg" alt="vvavatar" width="250" height="171" />';
  }

  makeCircularProgressbar() {
    return '<br><br><br><h2>Circular Progress</h2><br><div class="progress-circle over50 p80"><span>80%</span><div class="left-half-clipper"><div class="first50-bar"/><div class="value-bar"/></div></div>';
  }

  makeProgressStyle() {
    return '.progress-circle { font-size: 20px; margin: 20px; position: relative; padding: 0; width: 5em; height: 5em; background-color: #F2E9E1; border-radius: 50%; line-height: 5em; } .progress-circle:after{ border: none; position: absolute; top: 0.35em; left: 0.35em; text-align: center; display: block; border-radius: 50%; width: 4.3em; height: 4.3em; background-color: white; content: " "; } .progress-circle span { position: absolute; line-height: 5em; width: 5em; text-align: center; display: block; color: #53777A; z-index: 2; } .left-half-clipper { border-radius: 50%; width: 5em; height: 5em; position: absolute; clip: rect(0, 5em, 5em, 2.5em); } .progress-circle.over50 .left-half-clipper { clip: rect(auto,auto,auto,auto); } .value-bar { position: absolute; clip: rect(0, 2.5em, 5em, 0); width: 5em; height: 5em; border-radius: 50%; border: 0.45em solid #53777A; box-sizing: border-box; } .progress-circle.over50 .first50-bar { position: absolute; clip: rect(0, 5em, 5em, 2.5em); background-color: #53777A; border-radius: 50%; width: 5em; height: 5em; } .progress-circle:not(.over50) .first50-bar{ display: none; } .progress-circle.p0 .value-bar { display: none; } .progress-circle.p1 .value-bar { transform: rotate(4deg); } .progress-circle.p2 .value-bar { transform: rotate(7deg); } .progress-circle.p3 .value-bar { transform: rotate(11deg); } .progress-circle.p4 .value-bar { transform: rotate(14deg); } .progress-circle.p5 .value-bar { transform: rotate(18deg); } .progress-circle.p6 .value-bar { transform: rotate(22deg); } .progress-circle.p7 .value-bar { transform: rotate(25deg); } .progress-circle.p8 .value-bar { transform: rotate(29deg); } .progress-circle.p9 .value-bar { transform: rotate(32deg); } .progress-circle.p10 .value-bar { transform: rotate(36deg); } .progress-circle.p11 .value-bar { transform: rotate(40deg); } .progress-circle.p12 .value-bar { transform: rotate(43deg); } .progress-circle.p13 .value-bar { transform: rotate(47deg); } .progress-circle.p14 .value-bar { transform: rotate(50deg); } .progress-circle.p15 .value-bar { transform: rotate(54deg); } .progress-circle.p16 .value-bar { transform: rotate(58deg); } .progress-circle.p17 .value-bar { transform: rotate(61deg); } .progress-circle.p18 .value-bar { transform: rotate(65deg); } .progress-circle.p19 .value-bar { transform: rotate(68deg); } .progress-circle.p20 .value-bar { transform: rotate(72deg); } .progress-circle.p21 .value-bar { transform: rotate(76deg); } .progress-circle.p22 .value-bar { transform: rotate(79deg); } .progress-circle.p23 .value-bar { transform: rotate(83deg); } .progress-circle.p24 .value-bar { transform: rotate(86deg); } .progress-circle.p25 .value-bar { transform: rotate(90deg); } .progress-circle.p26 .value-bar { transform: rotate(94deg); } .progress-circle.p27 .value-bar { transform: rotate(97deg); } .progress-circle.p28 .value-bar { transform: rotate(101deg); } .progress-circle.p29 .value-bar { transform: rotate(104deg); } .progress-circle.p30 .value-bar { transform: rotate(108deg); } .progress-circle.p31 .value-bar { transform: rotate(112deg); } .progress-circle.p32 .value-bar { transform: rotate(115deg); } .progress-circle.p33 .value-bar { transform: rotate(119deg); } .progress-circle.p34 .value-bar { transform: rotate(122deg); } .progress-circle.p35 .value-bar { transform: rotate(126deg); } .progress-circle.p36 .value-bar { transform: rotate(130deg); } .progress-circle.p37 .value-bar { transform: rotate(133deg); } .progress-circle.p38 .value-bar { transform: rotate(137deg); } .progress-circle.p39 .value-bar { transform: rotate(140deg); } .progress-circle.p40 .value-bar { transform: rotate(144deg); } .progress-circle.p41 .value-bar { transform: rotate(148deg); } .progress-circle.p42 .value-bar { transform: rotate(151deg); } .progress-circle.p43 .value-bar { transform: rotate(155deg); } .progress-circle.p44 .value-bar { transform: rotate(158deg); } .progress-circle.p45 .value-bar { transform: rotate(162deg); } .progress-circle.p46 .value-bar { transform: rotate(166deg); } .progress-circle.p47 .value-bar { transform: rotate(169deg); } .progress-circle.p48 .value-bar { transform: rotate(173deg); } .progress-circle.p49 .value-bar { transform: rotate(176deg); } .progress-circle.p50 .value-bar { transform: rotate(180deg); } .progress-circle.p51 .value-bar { transform: rotate(184deg); } .progress-circle.p52 .value-bar { transform: rotate(187deg); } .progress-circle.p53 .value-bar { transform: rotate(191deg); } .progress-circle.p54 .value-bar { transform: rotate(194deg); } .progress-circle.p55 .value-bar { transform: rotate(198deg); } .progress-circle.p56 .value-bar { transform: rotate(202deg); } .progress-circle.p57 .value-bar { transform: rotate(205deg); } .progress-circle.p58 .value-bar { transform: rotate(209deg); } .progress-circle.p59 .value-bar { transform: rotate(212deg); } .progress-circle.p60 .value-bar { transform: rotate(216deg); } .progress-circle.p61 .value-bar { transform: rotate(220deg); } .progress-circle.p62 .value-bar { transform: rotate(223deg); } .progress-circle.p63 .value-bar { transform: rotate(227deg); } .progress-circle.p64 .value-bar { transform: rotate(230deg); } .progress-circle.p65 .value-bar { transform: rotate(234deg); } .progress-circle.p66 .value-bar { transform: rotate(238deg); } .progress-circle.p67 .value-bar { transform: rotate(241deg); } .progress-circle.p68 .value-bar { transform: rotate(245deg); } .progress-circle.p69 .value-bar { transform: rotate(248deg); } .progress-circle.p70 .value-bar { transform: rotate(252deg); } .progress-circle.p71 .value-bar { transform: rotate(256deg); } .progress-circle.p72 .value-bar { transform: rotate(259deg); } .progress-circle.p73 .value-bar { transform: rotate(263deg); } .progress-circle.p74 .value-bar { transform: rotate(266deg); } .progress-circle.p75 .value-bar { transform: rotate(270deg); } .progress-circle.p76 .value-bar { transform: rotate(274deg); } .progress-circle.p77 .value-bar { transform: rotate(277deg); } .progress-circle.p78 .value-bar { transform: rotate(281deg); } .progress-circle.p79 .value-bar { transform: rotate(284deg); } .progress-circle.p80 .value-bar { transform: rotate(288deg); } .progress-circle.p81 .value-bar { transform: rotate(292deg); } .progress-circle.p82 .value-bar { transform: rotate(295deg); } .progress-circle.p83 .value-bar { transform: rotate(299deg); } .progress-circle.p84 .value-bar { transform: rotate(302deg); } .progress-circle.p85 .value-bar { transform: rotate(306deg); } .progress-circle.p86 .value-bar { transform: rotate(310deg); } .progress-circle.p87 .value-bar { transform: rotate(313deg); } .progress-circle.p88 .value-bar { transform: rotate(317deg); } .progress-circle.p89 .value-bar { transform: rotate(320deg); } .progress-circle.p90 .value-bar { transform: rotate(324deg); } .progress-circle.p91 .value-bar { transform: rotate(328deg); } .progress-circle.p92 .value-bar { transform: rotate(331deg); } .progress-circle.p93 .value-bar { transform: rotate(335deg); } .progress-circle.p94 .value-bar { transform: rotate(338deg); } .progress-circle.p95 .value-bar { transform: rotate(342deg); } .progress-circle.p96 .value-bar { transform: rotate(346deg); } .progress-circle.p97 .value-bar { transform: rotate(349deg); } .progress-circle.p98 .value-bar { transform: rotate(353deg); } .progress-circle.p99 .value-bar { transform: rotate(356deg); } .progress-circle.p100 .value-bar { transform: rotate(360deg); }';
  }

  makeHorizontalProgress() {
    return '<br><br><h2>Horizontal Progress Demo</h2><div class="w3-light-grey w3-round-xlarge"><div class="w3-container w3-blue w3-round-xlarge" style="width:75%">75%</div></div>';
  }

  makeHorizontalProgress2() {
    return '<br><br><div class="w3-light-grey"><div class="w3-container w3-red w3-center" style="width:80%">80%</div></div><br>';
  }

  makeHorizontalProgress3() {
    return '<progress value="92" max="100"></progress><br><br>';
  }

  makeTableSplitTest() {
    return '<table style="width:100%" bgcolor="#00FF00"> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td><table style="width:100%" bgcolor="#00FF00"> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Table 2</th> </tr> <tr> <td>Jill2</td> </tr> <tr> <td>Eve2</td> </tr> <tr bgcolor="#ff0000"> <td>John</td> </tr> <tr> <th>Firstname</th> </tr> <tr> <td>Jill</td> </tr> <tr> <td>Eve</td> </tr> <tr bgcolor="#f000"> <td><table style="width:100%"> <tr> <th>Firstname</th> <th>Lastname</th> <th>Age</th> </tr> <tr> <td>Jill</td> <td>Smith</td> <td>50</td> </tr> <tr> <td>Eve</td> <td>Jackson</td> <td>94</td> </tr> <tr> <td>John</td> <td>Doe</td> <td><table style="width:100%"> <tr> <th>Firstname</th> <th>Lastname</th> <th>Age</th> </tr> <tr> <td>Jill</td> <td>Smith</td> <td>50</td> </tr> <tr> <td>Eve</td> <td>Jackson</td> <td>94</td> </tr> <tr> <td>John</td> <td>Doe</td> <td>80</td> </tr> </table></td> </tr> </table></td> </tr> </table></td> </tr> </table>';
  }

  makeCard() {
    return '<br><br><br><br><br><br><br><div class="w3-container"><h2>Card Content Demo</h2><div class="w3-card-4" style="width:50%;"><header class="w3-container w3-blue"><h1>Header</h1></header><div class="w3-container"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut laboris nisi ut aliquip ex ea commodo consequat.</p></div><footer class="w3-container w3-blue"><h5>Footer</h5></footer></div></div>';
  }

  makeCircularFill() {
    return '';
  }

  testIconLinkRel() {
    return '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">';
  }

  testIcon() {
    return '<p>Some Bootstrap icons:</p> <i class="glyphicon glyphicon-cloud"></i> <i class="glyphicon glyphicon-remove"></i> <i class="glyphicon glyphicon-user"></i> <i class="glyphicon glyphicon-envelope"></i> <i class="glyphicon glyphicon-thumbs-up"></i> <br><br> <p>Styled Bootstrap icons (size and color):</p> <i class="glyphicon glyphicon-cloud" style="font-size:24px;"></i> <i class="glyphicon glyphicon-cloud" style="font-size:36px;"></i> <i class="glyphicon glyphicon-cloud" style="font-size:48px;color:red;"></i> <i class="glyphicon glyphicon-cloud" style="font-size:60px;color:lightblue;"></i>';
  }

  getNewCeesRel() {
    return '<link rel="stylesheet" type="text/css"  href="file:///android_asset/flutter_assets/assets/css/all.css">';
  }

  newCssLinkRel() {
    return '<br><h2>New Local Icon test</h2><i class="fas fa-user"></i>  <i class="far fa-user"></i>  <i class="fal fa-user"></i>   <i class="fab fa-github-square"></i> <br><br>';
  }
}

pubspec.yaml

  pdf: ^1.3.17
  printing: ^2.1.4
  flutter_full_pdf_viewer: ^1.0.4


from Icons not rendering in PDF when creating views using HTML, CSS in Flutter app. How to use font-awesome library in Flutter-app locally?

No comments:

Post a Comment