iText error while trying to set an image field - java

I am using iText 5.3.4 and trying to set an image field, the below code is what Bruno suggested that I use however I am getting an error of "The type of the expression must be an array type but it resolved to List".
I see no documentation on how to write the code the way that the api is asking for.
Does anyone have an idea on how this should be written????
Or how to send an image to an image field?
Rectangle rect = form.getFieldPositions(fieldName)[0].position;
int page = form.getFieldPositions(fieldName)[0].page;
image1.scaleAbsolute(rect.getWidth(), rect.getHeight());
img.setAbsolutePosition(rect.getLeft(), rect.getBottom());
stamper.getOverContent(page).addImage(img);

The return from getFieldPositions is of type List<AcroFields.FieldPosition>, so the complaint is valid. You should use .get(0) rather than [0] to reference the first item in the collection.
A simple refactoring might be:
List<AcroFields.FieldPosition> positions = form.getFieldPositions(fieldName);
Rectangle rect = positions.get(0).position;
int page = positions.get(0).page;
image1.scaleAbsolute(rect.getWidth(), rect.getHeight());
img.setAbsolutePosition(rect.getLeft(), rect.getBottom());
stamper.getOverContent(page).addImage(img);

Related

JasperReports export to Excel uses only last set background color

Im pretty pretty new to Dynamic-Jasper, but due to work i had to add a new feature to our already implemented solution.
My Problem
The Goal is to add a Column to a report that consists only out of a background-color based on some Information. I managed to do that, but while testing I stumbled upon a Problem. While all my Columns in the html and pdf view had the right color, the Excel one only colored the fields in the last Color.
While debugging i noticed, that the same colored Fields had the same templateId, but while all Views run through mostly the same Code the Excel one showed different behavior and had the same ID in all fields.
My Code where I manipulate the template
for(JRPrintElement elemt : jasperPrint.getPages().get(0).getElements()) {
if(elemt instanceof JRTemplatePrintText) {
JRTemplatePrintText text = (JRTemplatePrintText) elemt;
(...)
if (text.getFullText().startsWith("COLOR_IDENTIFIER")) {
String marker = text.getFullText().substring(text.getFullText().indexOf('#') + 1);
text.setText("ID = " + ((JRTemplatePrintText) elemt).getTemplate().getId());
int rgb = TypeConverter.string2int(Integer.parseInt(marker, 16) + "", 0);
((JRTemplatePrintText) elemt).getTemplate().setBackcolor(new Color(rgb));
}
}
}
The html view
The Excel view
Temporary Conclusion
The same styles uses the same Objects in the background and the JR-Excel export messes something up by assigning the same Object to all the Fields that I manipulated there. If anyone knows of a misstake by me or potential Solutions to change something different to result the same thing please let me know.
Something different I tried earlier, was trying to set the field in an evaluate Method that was called by Jasper. In that method we assign the textvalue of each field. It contained a map with JRFillFields, but unfortunatelly the Map-Implementation denied access to them and just retuned the Value of those. The map was provided by dj and couldn't be switched with a different one.
Edit
We are using JasperReports 6.7.1
I found a Solution, where I replaced each template with a new one that was supposed to look exactly alike. That way every Field has its own ID guaranteed and its not up to chance, how JasperReports handles its Data internaly.
JRTemplateElement custom =
new JRTemplateText(((JRTemplatePrintText) elemt).getTemplate().getOrigin(),
((JRTemplatePrintText) elemt).getTemplate().getDefaultStyleProvider());
custom.setBackcolor(new Color(rgb));
custom.setStyle(((JRTemplatePrintText) elemt).getTemplate().getStyle());
((JRTemplatePrintText) elemt).setTemplate(custom);

adding sticky Notes to pdf using pdfbox

I am trying to add sticky notes to an existing pdf using pdfbox.
PDRectangle position = new PDRectangle();
System.out.println(textPosition.getXDirAdj());
position.setUpperRightX(textPosition.getX());
position.setUpperRightY(ph - textPosition.getY());
PDAnnotationTextMarkup polygonMarkup = new PDAnnotationTextMarkup(PDAnnotationMarkup.SUB_TYPE_POLYGON);
polygonMarkup.setContents("text");
polygonMarkup.setRectangle(position);
polygonMarkup.setLocked(true);
polygonMarkup.setReadOnly(true);
annotations.add(polygonMarkup);
page.setAnnotations(annotations);
this code is working fine, but it doesn't create a sticky Note which is my primary concern.
any leads are appreciated.
As Quoted by #mkl
According to the PDF specification, 'a text annotation represents a “sticky note” attached to a point in the PDF document.' Thus, neither the class PDAnnotationTextMarkup nor the subtype SUB_TYPE_POLYGON appears to match your requirements. Instead, you should use the PDAnnotationText class. As an aside, PDAnnotationTextMarkup is documented (JavaDocs) to be the abstract class that represents a text markup annotation. While it is not actually declared abstract, that characterization should make clear that it probably does not work without further ado.
so I used the below code and it worked like magic for me
PDRectangle position = new PDRectangle();
position.setUpperRightX(textPosition.getX());
position.setUpperRightY(ph - textPosition.getY());
position.setLowerLeftX(textPosition.getX()-4);
position.setLowerLeftY(ph - textPosition.getY());
PDGamma colourBlue = new PDGamma();
colourBlue.setB(1);
PDAnnotationText text = new PDAnnotationText();
text.setContents(commentNameWithComments.get(word));
text.setRectangle(position);
text.setOpen(true);
text.setConstantOpacity(50f);
assert annotations != null;
annotations.add(text);
page1.setAnnotations(annotations);
replaceText(word);
it might be useful for future devs :-)

How to get image dimensions in Magnolia CMS

I have an absolute positioned image whose parent container I need to set a height on, but now I can't find a method in magnolia API that allows me to get the width or height of an asset/item.
Is there a way to get Image Dimensions (height, width) of an Asset/Item in Magnolia CMS using only the native API?
If not, how would you do it?
I would write it somehow like
import info.magnolia.dam.api.metadata.MagnoliaAssetMetadata;
// ...
if (asset.supports(MagnoliaAssetMetadata.class)) {
MagnoliaAssetMetadata metadata = asset.getMetadata(MagnoliaAssetMetadata.class);
long width = metadata.getWidth();
long height = metadata.getHeight();
// do whatever you need with the image dimensions
} else {
// handle non-image asset
}
See MagnoliaAssetMetadata javadoc and/or sources (and related classes) for more info.
I have done something like this, base on what you have suggested. I am using damTemplatingFunctions to get the asset using the JCR id.
Node node = nodes.nextNode();
String imageJcrId = node.getProperty("image").getValue().getString();
Asset asset = damTemplatingFunctions.getAsset(imageJcrId);
MagnoliaAssetMetadata metadata1 = asset.getMetadata(MagnoliaAssetMetadata.class);
System.out.println(metadata1.getHeight());
System.out.println(metadata1.getWidth());

Icepdf annotation let page disappear

I'm developing an application that use Icepdf to show a pdf and draw something upon it.
I have a square annotation floating over the page but i have a nasty issue.
If i change page and come back to the page where the annotation is visible, if i move the annotation by dragging it the content of the page disappear becoming completely blank. This is the portion of code i use to show the moving annotation on top of the pdf.
Probably I'm missing something or doing it in wrong way.
controller.setAnnotationPanel(null);
controller.setDocumentToolMode(DocumentViewModelImpl.DISPLAY_TOOL_SELECTION); controller.getDocumentViewController().setViewCursor(DocumentViewController.CURSOR_SELECT);
Rectangle bbox = new Rectangle((int) (getPageWidth(getLastPage()) - SIGN_BOX_WIDTH - SIGN_BOX_MARGIN), SIGN_BOX_MARGIN, SIGN_BOX_WIDTH, SIGN_BOX_HEIGHT);
int index = getLastPage() - 1;
Document document = controller.getDocument();
DocumentViewModel documentViewModel=controller.getDocumentViewController().getDocumentViewModel();
PageTree pageTree = document.getPageTree();
Page page = pageTree.getPage(index);
// create and init the page's annotation components. [b]
java.util.List<AbstractPageViewComponent> pageComponents=controller.getDocumentViewController().getDocumentViewModel().getPageComponents();
AbstractPageViewComponent pageViewComponent = pageComponents.get(getLastPage() - 1);
tsq = (SquareAnnotation) AnnotationFactory.buildAnnotation(controller.getDocument().getPageTree().getLibrary(),Annotation.SUBTYPE_SQUARE,bbox);
BorderStyle bs = new BorderStyle();
bs.setBorderStyle(BorderStyle.BORDER_STYLE_SOLID);
bs.setStrokeWidth(2.0f);
tsq.setColor(Color.red);
tsq.setBorderStyle(bs);
tsq.setBBox(bbox);
tsq.setRectangle(bbox);
AffineTransform at = controller.getDocument().getPageTree().getPage(getLastPage() - 1).getPageTransform(controller.getDocumentViewController().getDocumentViewModel().getPageBoundary(), controller.getUserRotation(), controller.getUserZoom());
tsq.resetAppearanceStream(at);
SquareAnnotationComponent annotationComponent= (SquareAnnotationComponent) AnnotationComponentFactory.buildAnnotationComponent(tsq,controller.getDocumentViewController(),pageViewComponent,controller.getDocumentViewController().getDocumentViewModel());
annoCB.setCurrentAnnotation(annotationComponent);
controller.getDocument().getPageTree().getPage(getLastPage() - 1).addAnnotation(tsq);
Please assist to solve.
I had to work around on this, no real clue hot to solve.

Is it possible to add 'Open a web link action' action to acroform field programmatically using iText?

In Adobe Acrobat there is a possibility to add 'Open a web link action' to acroform. Is it possible to do so with iText usind already existing acroform?
I was unable to find any mention about it at iText docs and therefore tried to create new acrofield programmatically and add this action to it, but without success. Here's my code:
PdfReader pdfReader = new PdfReader(templateStream);
PdfStamper stamper = new PdfStamper(pdfReader, new FileOutputStream("delivery.pdf"));
stamper.setFormFlattening(true);
stamper.getAcroFields().setField("package", packages);
stamper.getAcroFields().setField("purchase_id", purchaseId);
stamper.getAcroFields().setField("activation_code", activationCode);
if (partner != "") {
PdfFormField field = PdfFormField.createTextField(stamper.getWriter(), false,
false, 100);
field.setFieldName("partner");
PdfAction action = new PdfAction(partner);
field.setAction(action);
field.setColor(new BaseColor(0,0,255));
PdfAppearance appearance = stamper.getUnderContent(1).
createAppearance(200, 20);
appearance.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12f);
appearance.setColorFill(BaseColor.BLUE);
field.setAppearance(PdfAnnotation.APPEARANCE_DOWN, appearance);
field.setDefaultAppearanceString(appearance);
stamper.getAcroFields().setField("partner", "Click here to show partner's web site");
}
The resulting PDF document is shown without partner field. Please point me to some docs or to mistake at my code.
You are trying to add interactivity to a form. However, you are also throwing away all interactivity by using this line:
stamper.setFormFlattening(true);
You also claim that you are adding an extra field. As far as I can see, that claim is false. You create a field name field (and you create it the hard way; I would expect you to use the TextField class instead). However, I don't see you adding that field anywhere. I miss the following line:
stamper.addAnnotation(field, 1);
Note that this line doesn't make sense:
stamper.getAcroFields().setField("partner", "Click here to show partner's web site");
Why would you create a field first (and possibly add a caption) and then change it immediately afterwards? Why not create the field correctly from the start?
Finally, it seems that you want to create a button that can be clicked by people. Then why are you creating a text field? Wouldn't it make more sense to create a push button?
This is an example of a question to which a machine would respond: Too many errors... Maybe you should consider reading the documentation before trying to fix your code.

Categories