123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- import 'dart:convert';
- import 'dart:io';
- import 'dart:typed_data';
- import 'dart:ui' as x;
- import 'package:fis_lib_pdf/pdf_objects/report/report_helper/report_style_helper.dart';
- import 'package:flutter/services.dart';
- import 'package:pdf/widgets.dart' as pw;
- import 'package:fis_lib_report/report_info/report_info.dart';
- import '../pdf_objects/report/report_helper/report_dic.dart';
- import 'package:fis_common/js_plateform/js_platform.dart';
- ///PDF相关资源缓存
- class ResourcesCache {
- static final Map<String, pw.Font> pdfCustomFonts = <String, pw.Font>{};
- static final Map<String, pw.MemoryImage> _pdfCloudImages =
- <String, pw.MemoryImage>{};
- static const int C_CACHELENGTH = 100;
- static String currentPDFFileKey = "";
- static Uint8List? currentGivenPDFBinaryFile;
- static Future<bool> Function(String fileName, Uint8List file)? cacheSave;
- static Future<Uint8List?> Function(String fileName)? cacheGet;
- static final Map<String, Uint8List> _pdfDocs = <String, Uint8List>{};
- ///获得默认的字体
- static Future<pw.Font> cacheDefaultFont(String fontKey) async {
- if (pdfCustomFonts.containsKey(fontKey)) {
- return pdfCustomFonts[fontKey]!;
- }
- const fontName = "NotoSansSC-R.ttf";
- Uint8List? pwFontBytes =
- cacheGet == null ? null : await cacheGet?.call(fontName);
- if (pwFontBytes == null) {
- var fontBytes = await rootBundle.load('assets/fonts/$fontName');
- var pwFont = pw.Font.ttf(fontBytes);
- pdfCustomFonts.addEntries(<String, pw.Font>{fontKey: pwFont}.entries);
- if (cacheSave != null) {
- // cacheSave?.call(fontName, fontBytes.buffer.asUint8List());
- }
- return pwFont;
- }
- return pw.Font.ttf(ByteData.sublistView(pwFontBytes));
- }
- ///Demo用PDF
- static Future<Uint8List> getPDF() async {
- var data = await rootBundle.load('assets/222.jpg');
- return data.buffer.asUint8List();
- }
- ///缓存生成的PDF文件
- static void cachePDFBinarys(Uint8List pdfBinary) {
- _pdfDocs
- .addEntries(<String, Uint8List>{currentPDFFileKey: pdfBinary}.entries);
- }
- ///获取当前缓存PDF二进制文件
- static Uint8List? getCachedPDFBinarys() {
- return _pdfDocs[currentPDFFileKey];
- }
- ///清空PDF缓存
- static void clearCachedPDF() {
- _pdfDocs.clear();
- }
- ///根据fileToken获得缓存图片
- static pw.MemoryImage? getCacheCloudImages(String fileToken) {
- return _pdfCloudImages[fileToken];
- }
- ///缓存ReportInfo下的所有图片资源
- static Future<void> cacheAllCloudImages(FReportInfo reportInfo) async {
- if (_pdfCloudImages.length == C_CACHELENGTH) {
- _pdfCloudImages.clear();
- }
- var images = <String>[];
- await _flattenedAllTheCloudResources(reportInfo.headers, images);
- await _flattenedAllTheCloudResources(reportInfo.blocks, images);
- await _flattenedAllTheCloudResources(reportInfo.footers, images);
- await cacheNetworkResources(images);
- }
- static Future<void> cacheNetworkResources(List<String> images) async {
- for (var i in images) {
- if (_pdfCloudImages.containsKey(i)) {
- continue;
- }
- var fileId = _getFileIDFromFileToken(i);
- var imageCacheFile = await cacheGet?.call(fileId);
- if (imageCacheFile == null) {
- var value = await ReportStyleHelper.getMemoryImage(i);
- var compressed = await _compressImage(value);
- _pdfCloudImages
- .addEntries(<String, pw.MemoryImage>{i: compressed}.entries);
- await cacheSave?.call(fileId, compressed.bytes);
- } else {
- var memoryImage = pw.MemoryImage(imageCacheFile);
- _pdfCloudImages
- .addEntries(<String, pw.MemoryImage>{i: memoryImage}.entries);
- }
- }
- }
- static String _getFileIDFromFileToken(String fileToken) {
- var tokens = fileToken.split("/");
- var fileName = tokens.last.replaceAll("%", "");
- return fileName;
- }
- static Future<void> _flattenedAllTheCloudResources(
- List<IBlockElementInfo> infos, List<String> urls) async {
- for (var i in infos) {
- if (i is InputImageInfo) {
- urls.add("");
- }
- if (i is InputImageListInfo) {
- urls.addAll(i.selectedImages);
- }
- if (i is StaticImageInfo) {
- i.source = await _compressStaticImage(i);
- }
- if (i is RTTableInfo) {
- for (var cell in i.cells!.values) {
- for (var block in cell.blocks!) {
- if (block.elementInfos != null) {
- await _flattenedAllTheelementInfos(block.elementInfos!, urls);
- }
- if (block is InputImageInfo) {
- if (block.selectedImage.isNotEmpty) {
- urls.add(block.selectedImage);
- }
- }
- if (block is InputImageListInfo) {
- urls.addAll(block.selectedImages);
- }
- }
- }
- }
- if (i.elementInfos != null) {
- await _flattenedAllTheelementInfos(i.elementInfos!, urls);
- }
- }
- }
- static Future sleep() {
- return Future.delayed(const Duration(microseconds: 200), () => {});
- }
- static Future<void> _flattenedAllTheelementInfos(
- List<ElementInfo> infos, List<String> urls) async {
- for (var i in infos) {
- if (i is InputImageInfo) {
- if (i.selectedImage.isNotEmpty) {
- urls.add(i.selectedImage);
- }
- }
- if (i is InputImageListInfo) {
- urls.addAll(i.selectedImages);
- }
- if (i is StaticImageInfo) {
- i.source = await _compressStaticImage(i);
- }
- }
- }
- static _compressStaticImage(StaticImageInfo imageInfo) async {
- Uint8List bytes = const Base64Decoder().convert(imageInfo.source!);
- var memoryImage = pw.MemoryImage(bytes);
- var compressedData = await JSPlateForm.compressBigImage(
- imageInfo.source!, memoryImage.width!, memoryImage.height!, 100);
- return compressedData;
- }
- static Future<pw.MemoryImage> _compressImage(Uint8List imagebytes) async {
- var memoryImage = pw.MemoryImage(imagebytes);
- var imageSize = memoryImage.bytes.length / 1024;
- if (imageSize < 200) {
- print("PDF render not compress since too small");
- return memoryImage;
- }
- print("PDF render doing jpg compressing");
- var sourceBase64 = Base64Encoder().convert(imagebytes);
- var compressedData = await JSPlateForm.compressBigImage(
- sourceBase64, memoryImage.width!, memoryImage.height!, 100);
- var uin8ListData = Base64Decoder().convert(compressedData);
- var compresedData = pw.MemoryImage(uin8ListData);
- return compresedData;
- }
- }
|