How to read non-acroform PDF form fields with iTextG? - android

I am trying to populate a PDF template with a family tree. The root node is the descendent, and it branches out into each pair of ancestors.
I am using PDF stamper to populate the form that goes back 3 generations.
I have created the above form in Open Office 4.1.1. I added Label Fields using the Form Design Mode and exported to PDF with "Create Forms" checked and using PDF format (also tried FDF).
The following is my iTextG integration:
reader = new PdfReader( src );
stamper = new PdfStamper( reader, baos );
stamper.setFormFlattening( true );
form = stamper.getAcroFields();
xfa = form.getXfa();
Log.i("FamilyTreeStorage Form Type", ( xfa.isXfaPresent() )? "XFA Form":"AcroForm" );
Set<String> fields = form.getFields().keySet();
if ( !fields.isEmpty() ){
for( String key : fields ){
Log.i("FamilyTreeStorage", String.format("key= %s; type= %d;", key, form.getFieldType( key )) );
}
}else{
Log.i("FamilyTreeStorage", "AcroFields returned empty set.");
}
The thing is that the form.getFields() does read form fields properly in PDF docs that I have gotten from other sources that contain AcroForms. The PDF that I generated with Open Office only returns an empty set for acro fields. It thinks there is no acro form. How do I populate non-acro form forms with iTextG?

Related

How to send document to apps script kotlin android

Currently Iam sending string and image file as string. to sheet via Apps script (sheet extension). Now I need to send a document files like (.zip, .glb, .obj, .arp, etc) I need to send these type of files to google sheet. so now I need to make user selected files as .zip. so now I need to send that .zip file to google sheet. but I couldnt do that.
private fun startUploading() {
try {
val map: HashMap<String, String> = HashMap()
map["instagramLink"] = binding.creatorInstaID.text.toString()
map["tutorialLink"] = binding.youTubeLink.text.toString()
map["detailDescription"] = binding.detailDescription.text.toString()
map["coverImage"] = userImage!!
mainViewModel.saveProduct(map)
}
catch (e:Exception){
Toast.makeText(context, "Fill all the details", Toast.LENGTH_SHORT).show()
}
}
Here userImage is the user selected image which is converted as string.
other values are string values it can be sent to google sheet easily.
now how can i send a custom file types to google sheet. as like this.
The only workaround I found is converting the encode the file to base64. Then add the string of base64 to the Google Sheet. I made a sample file with a Zip file store in Google Drive. You might need to adjust the code as needed.
Also, remember that character limit of a Google Cell is 50,000, so I added an if statement in case the encode file has more than 50,000 characters and split the string in an array of 45000 characters.
Note: The same sample code can be use on any type of files.
function encode64() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1")
// get the file from Google Drive using the ID
let file = DriveApp.getFileById("Drive_Zip_File_ID");
//convert the zip file to blob
let file_in_blop = file.getBlob();
//convert the blop to bytes
let file_in_bytes = file_in_blop.getBytes();
//encode the bytes to base64
let encoded = Utilities.base64Encode(file_in_bytes);
//get the length of charactes from the base 64 encode
let length_string = encoded.length
//split the string to array in chunks less than 45000 characters
if (length_string > 50000){
const result = encoded.match(/.{1,45000}/g) ?? [];
for (let i = 0; i < result.length; i++) {
sheet.getRange(i+2,2).setValue(result[i]);
}
}else(sheet.getRange("B2").setValue(result));
}

How to add comments to images using xamarin

I am using xamarin forms and build sample app. The app has few fields and take image function. When user take an image, the image get saved in phone gallery and get renamed to data from fields.
I have a notes field. In notes field user can enter some text and characters. I don't want to include data from note fields to rename image.
What I want is to get the user input from notes field and save in image comments. (Please see image below).
image comment
My first question is it possible to do that. So user fill some fields, take picture, and whatever user type in notes field; it can get saved in imagedetails->comments.
This is code to save image and rename to some data input fields.
I am using jamesmontemagno/MediaPlugin plugin to take images.
https://github.com/jamesmontemagno/MediaPlugin
private async void Take_Photo_Button_Clicked(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera available.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
SaveToAlbum = true,
//Directory = "Sample",
Name = jobnoentry.Text + "-" + Applicationletter + "-" + signnoentry.Text + "-" + Phototypeentry,
});
if (file == null)
return;
MainImage.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
});
You can see I assign Name of image to some data fields. But how i can add notes to annotate the image and have them in image comments.
Hope you all understand my question.
It's not clear what file type is the image being stored as. Is it a .png? a .jpeg? The library's example seems to indicate it stores JPEG files.
If that's the case, look into editing EXIF data. i.e. https://developer.xamarin.com/api/type/Android.Media.ExifInterface/

How to correctly add signature fields in a PDF/A document with iText

I'm trying to add N signature fields in a PDF/A document with iText API.
These fields have been correctly added using addAnnotation of PDFStamper, but the document is no longer PDF/A compliant.
In the PDF validation I get the following error:
The XMP property 'xmp:ModifyDate' is not synchronized with the document information entry 'ModDate'
How can I get a document conforms to the PDF/A standard?
Update: Now I'm using PdfAStamper (itext-pdfa-5.5.1) and itextg (itextg-5.5.1) for Android. But I get the same validation error-
Some code here:
String pdfFileName = pdfFile.getAbsolutePath();
PdfReader pdf = new PdfReader(pdfFileName);
tempFile = new File(pdfFileName.substring(0, pdfFileName.lastIndexOf(File.separator)) + "/_pdfSignFieldtemp_" + pdfFile.getName());
tempOutStream = new FileOutputStream(tempFile.getAbsolutePath());
PdfStamper stp = new PdfStamper(pdf, tempOutStream);
PdfFormField sig = PdfFormField.createSignature(stp.getWriter());
(...cut...)
sig.setWidget(new Rectangle(llx, lly, urx, ury), null);
sig.setAppearance(PdfAnnotation.APPEARANCE_NORMAL,PdfTemplate.createTemplate(stp.getWriter(), 0, 0));
sig.setFlags(PdfAnnotation.FLAGS_PRINT);
sig.setFieldFlags(PdfFormField.FF_REQUIRED);
sig.put(PdfName.DA, new PdfString("/Arial 0 Tf 0 g"));
sig.setFieldName(signatureName);
stp.addAnnotation(sig, intpage);
stp.close();
pdf.close();
tempOutStream.close();
pdfFile.delete();
File pdfWithField = new File(pdfFileName.substring(0, pdfFileName.lastIndexOf(File.separator)) + "/_pdfSignFieldtemp_" + pdfFile.getName());
pdfWithField.renameTo(new File(pdfFileName));
The XMP property 'xmp:ModifyDate' is not synchronized with the document information entry 'ModDate'
Both properties should have the same name, meaning xmp:ModifyDate and 'ModifyDate' (instead of ModDate)
P.S. It is an old topic, but still someone might find this answer useful.

How to send SharedObject Array data to PHP WS for DB Query (Flex)

I am currently developing an Android application using Flex 4.5.1 and I am having an issue when trying to pass data that I have stored in a SharedObject array to my Web Service for a Database query. the code below shows how I am storing the data in the SharedObject:
var so:SharedObject = SharedObject.getLocal("app");
public var prefsArray:ArrayCollection = new ArrayCollection(so.data.prefs);
protected function prefs_btn_click(event:MouseEvent):void
{
prefsArray.source.push(getFrsByIDResult.lastResult.id);
so.data.prefs = [prefsArray];
var flushStatus:String = so.flush();
if (flushStatus != null) {
switch(flushStatus) {
case SharedObjectFlushStatus.PENDING:
so.addEventListener(NetStatusEvent.NET_STATUS,
onFlushStatus);
break;
case SharedObjectFlushStatus.FLUSHED:
trace("success");
break;
}
}
}
protected function onFlushStatus(event:NetStatusEvent):void
{
trace(event.info.code);
}
I have tested the SharedObject to see if the information is being entered into it correctly and all seems fine. Now I have used the code below in order to retrieve the data from the SharedObject and try and send it to the PHP web Service to run the DB query.
var so:SharedObject = SharedObject.getLocal("app");
var arrCol:ArrayCollection = new ArrayCollection(so.data.prefs);
var str:String = new String(arrCol.toString());
protected function list_creationCompleteHandler(event:FlexEvent):void
{
getPrefsByprefIdsResult.token = prefsService.getPrefsByPrefIds(so.data.prefs);
}
I have tested the Webservice in Flex and have it configured to recieve an Array of Ints (int[]) and it works when i run a test operation on it with two dummy values. However when I try to use the code above to pass the Web Service the Shared Object data I get this error:
TypeError: Error #1034: Type Coercion failed: cannot convert []#97e97e1 to mx.collections.ArrayCollection.
at views::**************/list_creationCompleteHandler()[C:\Users\Jack\Adobe Flash Builder 4.5\****************\src\views\*******************.mxml:25]
at views::*********************/__list_creationComplete()[C:\Users\Jack\Adobe Flash Builder 4.5\****************\src\views\***************.mxml:94]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:13128]
at mx.core::UIComponent/set initialized()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:1818]
at mx.managers::LayoutManager/validateClient()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1090]
at mx.core::UIComponent/validateNow()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:8067]
at spark.components::ViewNavigator/commitNavigatorAction()[E:\dev\4.5.1\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1878]
at spark.components::ViewNavigator/commitProperties()[E:\dev\4.5.1\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1236]
at mx.core::UIComponent/validateProperties()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:8209]
at mx.managers::LayoutManager/validateProperties()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:597]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:783]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]
I have replaced certain filenames and locations with *'s to protect the work i am doing, but can someone please help me with this issues as I believe it has to be something simple???
Thanks
ok so let me explain in more detail. This is being designed for an Android app like I said, but image what I am trying to do is to store Bookmarks persistently using the Local Shared Object.
The first chunck of code you see above is designed to create the LSO attribute for the bookmark i want to create and imagine that there can be more than one bookmark set at different times like in a web browser. The only way i could find to do this was to store these items/details in an array which I retrieve and then update before saving back to the LSO and saving.
The second piece of code related to imagine a "Bookmarks Page" with a list of all the content that I have bookmarked. Now what I wanted to happen was thta I would be able to call up the LSO attribute which held the id's of the bookmarks and then load up thier details in a list format.
I have managed to create the LSO and store the bookmark deatils in and allow them to be updated and entries added. Also I have made sure that the PHP code that I have pulls back all the database objects relating to the array of id's and this has been tested using flex. The only thing that I cant seem to do is to pass the id's to the PHP web service file. The code in the Web Service file is below if that helps:
public function getPrefsByPrefIds($PrefIds) {
$stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename WHERE $this->tablename.id IN(" .implode(",", $PrefIds). ")");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
mysqli_stmt_bind_result($stmt, $row->id, $row->name, $row->desc);
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->id, $row->name, $row->desc);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
Yes I had already tried that but thanks. I have made some more progress on my own as I have been experimenting with the different types of objects that can be stored in SharedObjects. I have managed to get the solution part working with this code:
This code is designed to capture the boomark info and store it in an arrayCollection before transferring it to a bytesArray and saving
var so:SharedObject = SharedObject.getLocal("app");
public var prefArray:ArrayCollection = new ArrayCollection(so.data.prefs);
protected function prefs_btn_click(event:MouseEvent):void
{
prefArray.source.push(getCompaniesByIDResult.lastResult.id);
so.data.prefs = [prefArray];
var bytes:ByteArray = new ByteArray();
bytes.writeObject(prefArray);
so.data.ac = bytes;
var flushStatus:String = so.flush();
if (flushStatus != null) {
switch(flushStatus) {
case SharedObjectFlushStatus.PENDING:
so.addEventListener(NetStatusEvent.NET_STATUS,
onFlushStatus);
break;
case SharedObjectFlushStatus.FLUSHED:
trace("success");
break;
}
}
}
protected function onFlushStatus(event:NetStatusEvent):void
{
trace(event.info.code);
}
This next code is the designed to retrieve that information from the SahredObjects bytesArray and put it back into an Array Collection
var so:SharedObject = SharedObject.getLocal("app");
var ba:ByteArray = so.data.ac as ByteArray;
var ac:ArrayCollection;
protected function list_creationCompleteHandler(event:FlexEvent):void
{
ba.position = 0;
ac = ba.readObject() as ArrayCollection;
getPrefsByPrefIdsResult.token = prefsService.getPrefsByPrefIds(ac);
}
however as I have said this works in a small way only as if I store only one Bookmark (id) for an item and then go to the bookmarks list the details for that bookark are successfully retrieved, however if I save more than one Bookmark(2 or more id's) the page will not load the details, i do not get an error but I believe it is hanging because it is looking for say id's "1,2" instead of "1" and "2" but i dont know why this is or how to resolve this. I appreciate the advice I have been given but am finding it hard there is no one who can help me with this issue and I am having to do various experiemnts with the code. Can someone please help me with this I would really appreciate it :-) Thanks

Why are foreign characters not read using inputStream?

I have a text file which contains data I need to preload into a SQLite database. I saved in in res/raw.
I read the whole file using readTxtFromRaw(), then I use the StringTokenizer class to process the file line by line.
However the String returned by readTxtFromRaw does not show foreign characters that are in the file. I need these as some of the text is Spanish or French. Am I missing something?
Code:
String fileCont = new String(readTxtFromRaw(R.raw.wordstext));
StringTokenizer myToken = new StringTokenizer(fileCont , "\t\n\r\f");
The readTxtFromRaw method is:
private String readTxtFromRaw(Integer rawResource) throws IOException
{
InputStream inputStream = mCtx.getResources().openRawResource(rawResource);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i = inputStream.read();
while (i != -1)
{
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
return byteArrayOutputStream.toString();
}
The file was created using Eclipse, and all characters appear fine in Eclipse.
Could this have something to do with Eclipse itself? I set a breakpoint and checked out myToken in the Watch window. I tried to manually replace the weird character for the correct one (for example í, or é), and it would not let me.
Have you checked the several encodings?
what's the encoding of your source file?
what's the encoding of your output stream?
the byteArrayOutputStream.toString() converts according to the platform's default character encoding. So I guess it will strip the foreign characters or convert them in a way that they are not displayed in your output.
Have you already tried to use byteArrayOutputStream.toString(String enc)? Try "UTF-8" or "iso-8859-1" or "UTF-16" for the encoding.

Categories

Resources