itext pdf - how to combine headers and data when table splits - itext
Here is a sample code how I am displaying tables on pdf. Requirement is, when the table is going to split into multiple pages, the last row of this page (highlighted with gray background on the pdf) and the first row of the next page (white background) should displayed as combined. Most of the tables in our pdf have the same design to display multiple sections in a single table. Is it possible..? Please help!
public class PdfTest {
public static void main(String[] args) {
Document document = new Document();
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(document,
new FileOutputStream("C:/Users/SplitExample.pdf"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
document.open();
document.setPageSize(PageSize.LETTER);
document.setMargins(36, 36, 60, 36);
PdfTest pdfTest = new PdfTest();
pdfTest.createTable(document, writer);
document.close();
}
private void createTable(Document document, PdfWriter writer) {
try {
PdfPTable table = new PdfPTable(5);
float width[] = { 1, 1, 1, 1, 1 };
table.setWidths(width);
table.setTotalWidth(527);
table.setWidthPercentage(90);
document.add(new Paragraph("\n"));
document.add(new Paragraph("Table Header"));
document.add(new Paragraph("\n"));
for(int i=0; i<6; i++) {
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(getNameAndAgeCell("Person ", 25));
table.addCell(wrapStringToPdfPCellWithFormatting("Date", 1));
table.addCell(wrapStringToPdfPCellWithFormatting("Male", 1));
table.addCell(wrapStringToPdfPCellWithFormatting("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting("Eglish", 1));
table.addCell(buildTabularHeaders("Benefits", 4));
table.addCell(wrapStringToPdfPCellWithFormatting("No", 4));
table.addCell(buildTabularHeaders("Taxes", 4));
table.addCell(wrapStringToPdfPCellWithFormatting("Yes", 4));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Date", 1));
table.addCell(buildTabularHeaders("Citizen", 1));
table.addCell(buildTabularHeaders("Entry", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 2));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 2));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 2));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 2));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 2));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 2));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(buildTabularHeaders("Test", 2));
table.addCell(buildTabularHeaders("Test", 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 2));
table.addCell(wrapStringToPdfPCellWithFormatting(null, 1));
}
//addNewPage(writer, document, 80, table.getTotalHeight());
document.add(table);
} catch (Exception objExp) {
objExp.printStackTrace();
}
}
private PdfPCell getNameAndAgeCell(String name, int rowSpan) throws Exception {
PdfPCell nameAgeCell = new PdfPCell();
nameAgeCell.addElement(new Phrase("Name", FontFactory.getFont("ARIAL", 9)));
nameAgeCell.addElement(new Phrase("Age" + "20", FontFactory.getFont("ARIAL", 9)));
nameAgeCell.setRowspan(rowSpan);
return nameAgeCell;
}
private PdfPCell wrapStringToPdfPCellWithFormatting(String input, int colSpan) {
PdfPCell output = null;
if (input != null) {
output = new PdfPCell(new Phrase(input, FontFactory.getFont("ARIAL", 9)));
output.setPadding(1);
output.setColspan(colSpan);
} else {
output = new PdfPCell(new Phrase(INInterfacesHelper.SPACE_STRING , FontFactory.getFont("ARIAL", 9)));
output.setPadding(1);
output.setColspan(colSpan);
}
//output.setBorder(1);
return output;
}
private PdfPCell buildTabularHeaders(String strHeaderText, int colSpan) {
PdfPCell objHeadCell = new PdfPCell(new Phrase(strHeaderText,FontFactory.getFont(FontFactory.HELVETICA, 9,Font.BOLD)));
//objHeadCell.setHorizontalAlignment(Element.ALIGN_CENTER);
//objHeadCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
objHeadCell.setGrayFill(0.8f);
objHeadCell.setColspan(colSpan);
return objHeadCell;
}
private void addNewPage(PdfWriter writer, Document document, int tableHeaderHeight, float tableHeight) {
if ((writer.getVerticalPosition(true) - tableHeaderHeight - document.bottom()) < tableHeight) {
document.newPage();
}
}
}
When you add one table after the other, you won't see any difference: visually, the separate tables will look as if they are one.
Hence, you shouldn't use one large table to meet your requirement. Instead, you should start a new table each time you need a new header and use the setHeaderRows() method to define how many rows are part of the header. Those rows will be repeated automatically when the table is split.
Related
Flutter walk & draw polylines following current location
Using flutter_polyline_points: ^1.0.0 & google_maps_flutter: ^2.2.1 So what I am trying to achieve is to draw polylines on Google Map at flutter following current WALKING user location [using Geolocator]. The code below works, except when I stay out of the road, polylines are not drawn after my location [the location of blue dot at google maps] but they stick to the main road and won't cross it's boundaries... (https://i.stack.imgur.com/FHV2d.jpg) CountDown func is counting down to 0 and then showing map/location/timer etc [start walk] _CountDown() async { const oneSec = Duration(seconds: 1); _timer = Timer.periodic(oneSec, (timer) { _startTimer == 0 ? setState( () { timer.cancel(); _getCurrentLocation(); Future.delayed(const Duration(seconds: 5), () { stopWatchTimer.onStartTimer(); _updateMapAndValues(); }); }, ) : setState( () => _startTimer--, ); }); } _getCurrentLocation() is getting current position and sets late _currectPosition to later zoom on it with map. _getCurrentLocation() async { await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true) .then((Position position) async { setState(() { _currentPosition = position; mapController.animateCamera( CameraUpdate.newCameraPosition( CameraPosition( target: LatLng(position.latitude, position.longitude), zoom: 18.0, ), ), ); }); }).catchError((e) { print(e); }); } After that I am stopping the timer/updating the map. First I am getting current position to check if location changed, then I am creating polyline between old _currentposition and new position (later calc distance and coins but that's not that importand). _updateMapAndValues() async { bool petla = true; while (petla) { await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true) .then((Position position) async { await Future.delayed(const Duration(milliseconds: 500)); if (_currentPosition.latitude != position.latitude && _currentPosition.longitude != position.longitude) { _createPolylines(_currentPosition, position); await _calculateDistance(); setState(() { _currentPosition = position; int result = distance * 1000 ~/ 50; print('DYSTANS ILE COINOW : $result'); if (result > 0) { while (coins < result) { setState( () => coins++, ); } } }); } }); } } The _createPolylines function. I thought it will work adding travelMode:walking but it does not. Still (mostly) following the roads and when I am moving at the edges (screen) it just draw straight line. late PolylinePoints polylinePoints; List<LatLng> polylineCoords = []; Map<PolylineId, Polyline> polylines = {}; _createPolylines(Position start, Position end) async { polylinePoints = PolylinePoints(); PolylineResult result = await polylinePoints.getRouteBetweenCoordinates( 'AIzaSyDDyBb0N9_jthBS99PRJcT6CjFV2TI9J5E', PointLatLng(start.latitude, start.longitude), PointLatLng(end.latitude, end.longitude), travelMode: TravelMode.walking, avoidHighways: true, ); if (result.points.isNotEmpty) { result.points.forEach((element) { polylineCoords.add(LatLng(element.latitude, element.longitude)); print('--------WYSWIETLAM: $polylineCoords'); }); } PolylineId id = const PolylineId('poly'); Polyline polyline = Polyline( polylineId: id, color: Colors.red, points: polylineCoords, width: 5, ); polylines[id] = polyline; }
Can I use Async inside Dart Isolate ??? its not working
I am using ImageEditor package to merge different images. below is my code. its working perfectly fine without using Isolate, when i use it with isolate, i get null error. Working code without Isolate startEditing() async { for (var i = 0; i < image1.length || i == 0; i++) { if (image1.isNotEmpty) { img1 = await File(image1[i].path).readAsBytes(); } for (var i = 0; i < image2.length || i == 0; i++) { if (image2.isNotEmpty) { img2 = await File(image2[i].path).readAsBytes(); } final ImageEditorOption optionGroup = ImageEditorOption(); optionGroup.outputFormat = const OutputFormat.png(100); optionGroup.addOptions([ MixImageOption( x: 0, y: 0, width: 1000, height: 1000, target: MemoryImageSource(img1), ), MixImageOption( x: 0, y: 0, width: 1000, height: 1000, target: MemoryImageSource(img2), ), ]); try { final Uint8List? result = await ImageEditor.editImage( image: mainImg, imageEditorOption: optionGroup); if (result == null) { image = null; } else { await saveImage(result, index); setState(() { image = MemoryImage(result); index++; }); } } catch (e) { print(e); } } } } Code with Isolate not working startEditing(SendPort sendPort) async { for (var i = 0; i < image1.length || i == 0; i++) { if (image1.isNotEmpty) { img1 = await File(image1[i].path).readAsBytes(); } for (var i = 0; i < image2.length || i == 0; i++) { if (image2.isNotEmpty) { img2 = await File(image2[i].path).readAsBytes(); } final ImageEditorOption optionGroup = ImageEditorOption(); optionGroup.outputFormat = const OutputFormat.png(100); optionGroup.addOptions([ MixImageOption( x: 0, y: 0, width: 1000, height: 1000, target: MemoryImageSource(img1), ), MixImageOption( x: 0, y: 0, width: 1000, height: 1000, target: MemoryImageSource(img2), ), ]); try { final Uint8List? result = await ImageEditor.editImage( image: mainImg, imageEditorOption: optionGroup); if (result == null) { image = null; } else { await saveImage(result, index); image = MemoryImage(result); index++; sendPort.send(image); } } catch (e) { print(e); } } } } saveImage method Future<String> saveImage(Uint8List bytes, int i) async { final name = '${filenames[i]}'; final result = await ImageGallerySaver.saveImage(bytes, name: name); print(result); return result['filePath']; } Receiving in main thread getImageas() async { ReceivePort receiverPort = ReceivePort(); final isolate = await Isolate.spawn(startEditing, receiverPort.sendPort); receiverPort.listen((data) { print('Receiving: ' + data + ', '); }); } I get this error: I/flutter (21937): Null check operator used on a null value in this line: final Uint8List? result = await ImageEditor.editImage( image: mainImg, imageEditorOption: optionGroup); I am sure that img1, img2, mainImg, image1, image2 values are not null... check 1000 times. I have also used flutter compute, and same result.
Flutter plugins that call into native code (such as image_editor) do not work in isolates spawned by Isolate.spawn. The flutter_isolate package spawns isolates from native code for this reason. You should be able to use it to call image_editor in an isolate. (Disclaimer: I've never used flutter_isolate.)
difference between ref.watch(myProvider.state) and ref.watch(myProvider).state
I'm watching a provider's state in another provider. This is my StateProvider. final counterProvider = StateProvider<int>((ref) => 0); Now there are two ways to watch this. final isEvenProvider = Provider<bool>((ref) { final counter = ref.watch(counterProvider); // First return (counter.state % 2 == 0); }); final isEvenProvider = Provider<bool>((ref) { final counter = ref.watch(counterProvider.state); // Second return (counter % 2 == 0); }); What is the difference between the two? When should we use which?
Alert Dialog running infinitely
Hello I am trying to run following code, I want to run a specific asynchronous code and show alert dialog until it's running. But the code is not being executed after await showAlertDialog(); this line. void appendAndRunPythonCode() async { await showAlertDialog(); await runPythonScript(final_code); _alertDialogUtils.dismissAlertDialog(context); } This is how my showAlertDialog() function is implemented: Future<void> showAlertDialog() async { if (!_alertDialogUtils.isShowing) { await _alertDialogUtils.showAlertDialog(context); } } runPythonCode(): Future<void> runPythonScript(String code) async { if (inputImg == null) { ToastUtils.showToastMessage(text: ConstUtils.input_image_empty_notice); return; } if (code.isEmpty) { ToastUtils.showToastMessage(text: ConstUtils.code_empty); return; } List<String> lines = code.split('\n'); String lastLine = lines.elementAt(lines.length - 4); if (lastLine.split(' ').elementAt(0).compareTo('outputImage') != 0) { ToastUtils.showToastMessage(text: ConstUtils.cv_error_line2); return; } data.putIfAbsent("code", () => code); data.putIfAbsent("inputImg", () => inputImg); _alertDialogUtils.showAlertDialog(context); final result = await _channel.invokeMethod("runPythonCVScript", data); // Add Artifical Delay of 3 seconds.. await Future.delayed( Duration(seconds: 3), ); _alertDialogUtils.dismissAlertDialog(context); setState( () { _scrollController.animateTo( _scrollController.position.maxScrollExtent, curve: Curves.easeOut, duration: const Duration(milliseconds: 300), ); output = result['textOutput'] ??= ""; error = result['error'] ??= ""; outputImg = (result['graphOutput']); data.clear(); }, ); }
You shouldn't await the showAlertDialog because runPythonScript won't be executed until the dialog is dismissed. Remove the await. Like so: void appendAndRunPythonCode() async { showAlertDialog(); await runPythonScript(final_code); _alertDialogUtils.dismissAlertDialog(context); }
type 'future<dynamic>' is not a subtype of type 'function'
when i run my app in debug mode it shows me the error "type 'future' is not a subtype of type 'function'" all over the screen and also in the debug console. Can someone help me? I imagine it's a problem with async functions "reset","rateoGet" and "rateoSave" but i can't find any solution. P.S. I've deleted part of the code because it was useless for this question. int plus; int min; int per; int div; double val; int gameswon =0; int moves; static int mosse=15; String win = "gioca"; int games=0; double rateo=1; String mode; int flag; var timer=30; #override void initState() { super.initState(); reset(); } #override Widget build(BuildContext context) { return Scaffold( body: MyButton(text: "$per" ,color: Colors.deepPurpleAccent, onTap: (){ setState(() { val*=per; }); if(widget.mode=="timermode" && flag==0){ timerceckresults(); }else if(widget.mode=="movesmode"){ checkResult(); } }, MyBottomButton(text: "Reset",color: Colors.indigo,width:160, onTap: reset()), ), } checkResult() { if(val == 101) { print("hai vinto"); win="Hai Vinto"; setState(() {}); gameswon++; Timer(Duration(seconds: 2), () { reset(); }); } else { print("ci sei quasi"); moves++; mosse--; win="$mosse moves left"; setState(() {}); if(moves>14){ print("hai perso coglione"); win="Hai Perso Coglione"; setState(() {}); Timer(Duration(seconds: 2), () { reset(); }); } } } timerceckresults(){ flag=1; timer = 30; Timer.periodic(Duration(seconds: 1), (t){ timer--; setState(() { win = "${timer.toString()}seconds left"; }); if(val==101){ timer=0; } if(timer == 0) { t.cancel(); if(val == 101) { win="Hai Vinto"; setState(() {}); gameswon++; Timer(Duration(seconds: 2), () { reset(); }); } else { win="Hai Perso Coglione"; setState(() {}); Timer(Duration(seconds: 2), () { reset(); }); } } }); static int randNum(x,y) { var rng = new Random(); return rng.nextInt(y-x)+x; } reset() async{ timer=1; plus = randNum(4, 9); min = randNum(5, 19); per = randNum(3, 9); div = randNum(2, 5); val = randNum(2, 11).toDouble(); moves = 0; mosse=15; if(widget.mode=="timermode"){ win="start playing"; }else{ win="$mosse moves left"; } await rateoSave(); await rateoGet(); games++; rateo=gameswon/(games-1); await rateoSave(); flag=0; setState(() {}); } rateoSave() async { SharedPreferences prefs=await SharedPreferences.getInstance(); await prefs.setInt("games",games); await prefs.setInt("gameswon",gameswon); } rateoGet() async { SharedPreferences prefs=await SharedPreferences.getInstance(); games=(prefs.getInt("games") ?? 0); gameswon=(prefs.getInt("gameswon") ?? 0);
https://dart.dev/codelabs/async-await read this before you check the answer will help you alot reset() async{ timer=1; plus = randNum(4, 9); min = randNum(5, 19); per = randNum(3, 9); div = randNum(2, 5); val = randNum(2, 11).toDouble(); moves = 0; mosse=15; if(widget.mode=="timermode"){ win="start playing"; }else{ win="$mosse moves left"; } await rateoSave(); await rateoGet(); games++; rateo=gameswon/(games-1); await rateoSave(); flag=0; setState(() {}); } Future<bool> rateoSave() { SharedPreferences prefs= SharedPreferences.getInstance(); prefs.setInt("games",games); prefs.setInt("gameswon",gameswon); return true; } Future<bool> rateoGet() async { SharedPreferences prefs= SharedPreferences.getInstance(); await games=(prefs.getInt("games") ?? 0); await gameswon=(prefs.getInt("gameswon") ?? 0); return true; }
you are trying to get a variable from a method that returns a future. you need to add await just before you make the call to that function. can you tell us in which line this error occurs ?
The most important thing to keep in mind is that if anything in your call-chain returns a Future, everything above it must deal with futures, either by returning the future itself (if no processing must be done), or await'ing and dealing with the returned value (but you'll still be returning a future).