I have a text PDF with a string "Click Here".
How can I replace "Click Here" by a URL using PDFBox?
Aka "Click Here" will be in blue and clickable after the replacement in the updated (or new) PDF.
This is from the AddAnnotations.java example from the source code download:
PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary();
borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
borderULine.setWidth(1);
PDAnnotationLink txtLink = new PDAnnotationLink();
txtLink.setBorderStyle(borderULine);
// Set the rectangle containing the link
textWidth = font.getStringWidth("Click here") / 1000 * xscale;
position = new PDRectangle();
position.setLowerLeftX(...);
position.setLowerLeftY(...);
position.setUpperRightX(...);
position.setUpperRightY(...);
txtLink.setRectangle(position);
// add an action
PDActionURI action = new PDActionURI();
action.setURI("http://pdfbox.apache.org");
txtLink.setAction(action);
annotations.add(txtLink);
You'll need to know the coordinates of your "Click Here" and the x scaling factor and the font, obviously. In PDF, (0,0) is the bottom left. 1 Unit = 1/72 inch. It is easiest if you generate the file yourself. If it is an existing file, you'll have to analyse the file with PDFDebugger or do some trial and error.
Related
I am trying to set border, margin, and padding to a PDF document, is it possible to achieve using itext7
Margin works fine by setting below code
document.setLeftMargin(180);
But the border is not working, below code used to set the border
float width = 1.5f;
Color color = ColorConstants.BLUE;
Border border = new DottedBorder(color,width);
Document document = new Document(pdfDocument);
document.setBorder(border);
Unfortunately it's not possible to specify the document's background and borders just by setting some of the Document's properties. The good news is that iText7 provides us with an opportunity to override DocumentRenderer (renderers are classes responsible to render corresponding model objects, for example, ParagraphRenderer renders Paragraph and so on).
In the custom DocumentRenderer below updateCurrentArea was overridden to tackle the following two issues:
shrinking the area which will be used by DocumentRenderer to layout the Document's children
adding a background Div, whic will be resposible for border rendering (I've also shown how one could set background, if needed)
class CustomDocumentRenderer extends DocumentRenderer {
public CustomDocumentRenderer(Document document) {
super(document);
}
#Override
protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
LayoutArea area = super.updateCurrentArea(overflowResult); // margins are applied on this level
Rectangle newBBox = area.getBBox().clone();
// apply border
float[] borderWidths = {10, 10, 10, 10};
newBBox.applyMargins(borderWidths[0], borderWidths[1], borderWidths[2], borderWidths[3], false);
// this div will be added as a background
Div div = new Div()
.setWidth(newBBox.getWidth())
.setHeight(newBBox.getHeight())
.setBorder(new SolidBorder(10))
.setBackgroundColor(ColorConstants.GREEN);
addChild(new DivRenderer(div));
// apply padding
float[] paddingWidths = {20, 20, 20, 20};
newBBox.applyMargins(paddingWidths[0], paddingWidths[1], paddingWidths[2], paddingWidths[3], false);
return (currentArea = new RootLayoutArea(area.getPageNumber(), newBBox));
}
}
The last quetions is how to apply it on your document. It could be done as follows:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.setRenderer(new CustomDocumentRenderer(doc));
The resultant PDF:
I need to render the text field value correctly. I render the text field looks like the following:
final Rectangle rect = new Rectangle(100, page.getCropBox().getHeight() - (100 * pdf.getPageNumber(page)), 300, rectHeight);
field = PdfFormField.createText(pdf, rect, name);
field.setFontSize(14);
field.setValue(value);
field.setVisibility(VISIBLE);
form.addField(field, page);
and when I'm saving a pdf I have the result but when I'm trying to edit the following pdf using Acrobat Reader my text . How can I fix this issue?
I am using the following code to convert html>canvas>image
image.src = canvas.toDataURL('jpeg',1.0);
$('.imagediv').html(image);
////This is just a snippet
My problem is that I want do define the other image attributes width,height,alt,class and a neat file name image.jpg. Like you can see, the image needs to be displayed in the browser on conversion.
What you want to do is really simple (and the answer is in the sample code that you added): just define the different attributes in the same way that you did the image source:
.src: to specify the picture source.
.width: to specify the element's width.
.height: to specify the element's height.
.alt: to specify an alternative text.
.title: to specify the title.
.className: to specify the class.
.id: to specify the element id.
etc...
Or if you want, you could use the setAttribute() method instead:
image.setAttribute("alt", "I am the alternative text");
Here is a simple demo of setting different attributes to an image generated using canvas:
// get the canvas for manipulation
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');
// draw a square this is just a test
context.moveTo(5,5);
context.lineTo(395,5);
context.lineTo(395,195);
context.lineTo(5,195);
context.lineTo(5,5);
context.fillStyle = "#FF0000";
context.fillRect(5,5,390,190);
context.stroke();
// create the image and set the attributes
var image = new Image();
image.src = canvas.toDataURL('jpeg', 1.0);
image.alt = "A simple red rectangle with black border";
image.title = "Red rectangle with black border";
image.width = 400;
image.height = 200;
image.className = "myClass";
// place the image inside the div
document.getElementById('imagediv').appendChild( image );
.myClass {
box-shadow:2px 2px 8px red;
}
<canvas id="myCanvas" width="400" height="200" style="display:none;"></canvas>
<div id="imagediv"></div>
The only one that would be more complicated is the "neat file name". toDataURL method returns a data URI containing a representation of the image (in base64), and that's not a nice looking name. If you want to display a nice name, you will need to save the file and then point to it.
If what you want is a neat file name because the user will be able to download the picture using a link, what you can do is set the download attribute in the anchor and specify the name there.
Something like this:
// get the canvas for manipulation
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');
// draw a square this is just a test
context.moveTo(5,5);
context.lineTo(395,5);
context.lineTo(395,195);
context.lineTo(5,195);
context.lineTo(5,5);
context.fillStyle = "#FF0000";
context.fillRect(5,5,390,190);
context.stroke();
// set the image as the href of the anchor
document.getElementById("myA").href = canvas.toDataURL('jpeg', 1.0);
<canvas id="myCanvas" width="400" height="200" style="display:none;"></canvas>
Download picture
I am creating PPT files using the library docx4j. I have been able to create slides with text and images, but I have not been able to add notes to them.
I am creating the slide like this:
MainPresentationPart pp = (MainPresentationPart)presentationParts.get(new PartName("/ppt/presentation.xml"));
SlideLayoutPart layoutPart = (SlideLayoutPart)presentationParts.get(new PartName("/ppt/slideLayouts/slideLayout1.xml"));
SlidePart slidePart = PresentationMLPackage.createSlidePart(pp, layoutPart, new PartName("/ppt/slides/slide" + ++slideNumber + ".xml"));
so I can add text or images to the body, but when I try to access the field slidePart.notes it is null. I have tried to initialize it
slidePart.setPartShortcut(new NotesSlidePart());
but then everything inside notes is null and I have not achieved anything.
So, does anyone have a working example of how to add notes to a PPT file?
Many thanks
Its not enough to do:
slidePart.setPartShortcut(new NotesSlidePart());
You need to explicitly add the notes slide part to your slide part (so that the relationships get set up correctly), by invoking addTargetPart.
But there's more you have to do given the way the pptx format works. To see what parts are required, upload a pptx to the docx4j webapp. Here's the code I wrote just now based on doing that:
// Now add notes slide.
// 1. Notes master
NotesMasterPart nmp = new NotesMasterPart();
NotesMaster notesmaster = (NotesMaster)XmlUtils.unmarshalString(notesMasterXml, Context.jcPML);
nmp.setJaxbElement(notesmaster);
// .. connect it to /ppt/presentation.xml
Relationship ppRelNmp = pp.addTargetPart(nmp);
/*
* <p:notesMasterIdLst>
<p:notesMasterId r:id="rId3"/>
</p:notesMasterIdLst>
*/
pp.getJaxbElement().setNotesMasterIdLst(createNotesMasterIdListPlusEntry(ppRelNmp.getId()));
// .. NotesMasterPart typically has a rel to a theme
// .. can we get away without it?
// Nope .. read this in from a file
ThemePart themePart = new ThemePart(new PartName("/ppt/theme/theme2.xml"));
// TODO: read it from a string instead
themePart.unmarshal(
FileUtils.openInputStream(new File(System.getProperty("user.dir") + "/theme2.xml"))
);
nmp.addTargetPart(themePart);
// 2. Notes slide
NotesSlidePart nsp = new NotesSlidePart();
Notes notes = (Notes)XmlUtils.unmarshalString(notesXML, Context.jcPML);
nsp.setJaxbElement(notes);
// .. connect it to the slide
slidePart.addTargetPart(nsp);
// .. it also has a rel to the slide
nsp.addTargetPart(slidePart);
// .. and the slide master
nsp.addTargetPart(nmp);
You can find the complete example at https://github.com/plutext/docx4j/blob/master/src/samples/pptx4j/org/pptx4j/samples/SlideNotes.java
Is there a way of creating and inserting a bar chart in a Ms Word document using Aspose Words for Java? I can't find a way to do this. Thanks.
Aspose.Words for Java currently doesn't allow you to create the bar chart in Word documents. However, if you just want to add a static bar chart, you may try Aspose.Cells for Java to create bar chart and render it to image. After that, you can add this bar chart image in Word document using Aspose.Words for Java. Do you think this might help in your scenario? If it does then you can use the following code snippet to create and render the bar chart to image:
//Create a new Workbook.
Workbook workbook = new Workbook();
//Get the first worksheet.
Worksheet sheet = workbook.getWorksheets().get(0);
//Set the name of worksheet
sheet.setName("Data");
//Get the cells collection in the sheet.
Cells cells = workbook.getWorksheets().get(0).getCells();
//Put some values into a cells of the Data sheet.
cells.get("A1").setValue("Region");
cells.get("A2").setValue("France");
cells.get("A3").setValue("Germany");
cells.get("A4").setValue("England");
cells.get("A5").setValue("Sweden");
cells.get("A6").setValue("Italy");
cells.get("A7").setValue("Spain");
cells.get("A8").setValue("Portugal");
cells.get("B1").setValue("Sale");
cells.get("B2").setValue(70000);
cells.get("B3").setValue(55000);
cells.get("B4").setValue(30000);
cells.get("B5").setValue(40000);
cells.get("B6").setValue(35000);
cells.get("B7").setValue(32000);
cells.get("B8").setValue(10000);
//Create chart
int chartIndex = sheet.getCharts().add(ChartType.COLUMN, 12, 1, 33,
12);
Chart chart = sheet.getCharts().get(chartIndex);
//Set properties of chart title
chart.getTitle().setText("Sales By Region");
chart.getTitle().getTextFont().setBold(true);
chart.getTitle().getTextFont().setSize(12);
//Set properties of nseries
chart.getNSeries().add("Data!B2:B8", true);
chart.getNSeries().setCategoryData("Data!A2:A8");
//Set the fill colors for the series's data points (France -
Portugal(7 points))
ChartPointCollection chartPoints =
chart.getNSeries().get(0).getPoints();
ChartPoint point = chartPoints.get(0);
point.getArea().setForegroundColor(Color.getCyan());
point = chartPoints.get(1);
point.getArea().setForegroundColor(Color.getBlue());
point = chartPoints.get(2);
point.getArea().setForegroundColor(Color.getYellow());
point = chartPoints.get(3);
point.getArea().setForegroundColor(Color.getRed());
point = chartPoints.get(4);
point.getArea().setForegroundColor(Color.getBlack());
point = chartPoints.get(5);
point.getArea().setForegroundColor(Color.getGreen());
point = chartPoints.get(6);
point.getArea().setForegroundColor(Color.getMaroon());
//Set the legend invisible
chart.setShowLegend(false);
//Get the Chart mage
ImageOrPrintOptions imgOpts = new ImageOrPrintOptions();
imgOpts.setImageFormat(ImageFormat.getPng());
//Save the chart image file.
chart.toImage(new FileOutputStream("D:\Files\MyChartImage.png"),
imgOpts);
Disclosure: I work as developer evangelist at Aspose.