Empty PDF using XChart ChartPie as SVG ressource with PDFBoxGraphics2D and Salamander - java

I've been trying to compose a pie chart using XChart then vectorising it to SVG format to use it in a PDF built with PDFBox.
To do that, I use:
XChart for the pie chart building and vectorising it ;
SVGSalamender for the Graphics2D building based on previous SVG vectorising ;
PDFBoxGraphics2D for adding previous Graphics2D to my PDF.
Everything runs fine (in compiles and runs without errors) but it does not work. The output PDF stays empty.
This is my code:
#Test
public void test() {
try {
PieChart camembertXChart = camembertXChart();
BufferedImage imageCamembertXChart = BitmapEncoder.getBufferedImage(camembertXChart);
ByteArrayOutputStream output = new ByteArrayOutputStream();
File svg = new File("F:\\Users\\mangin\\Desktop\\Camembert_XChart.svg");
VectorGraphicsEncoder.saveVectorGraphic(camembertXChart, svg.getName(), VectorGraphicsFormat.SVG);
byte[] data = output.toByteArray();
FileInputStream input = new FileInputStream(svg);
BufferedImage imageCamembertXChartVectorise = ImageIO.read(input);
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contenu = new PDPageContentStream(document, page, AppendMode.APPEND, false, true);
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(document, 200, 200);
// SVG Salamander
SVGUniverse universSVG = new SVGUniverse();
SVGDiagram diagramSVG = universSVG.getDiagram(universSVG.loadSVG(svg.toURI().toURL()));
diagramSVG.render(pdfBoxGraphics2D);
pdfBoxGraphics2D.dispose();
var xform = pdfBoxGraphics2D.getXFormObject();
var transform = AffineTransform.getTranslateInstance(200, 200);
xform.setMatrix(transform);
contenu.drawForm(xform);
contenu.close();
document.save("D://tests/archi/PDF_avec_elements_graphique.pdf");
document.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private PieChart camembertXChart() {
PieChart camembert2 = new PieChartBuilder().width(200).height(200).build();
Color[] sliceColors = new Color[] {
new Color(183, 203, 231),
new Color(131, 173, 219),
new Color(84, 143, 197),
new Color(70, 120, 165) };
camembert2.getStyler().setSeriesColors(sliceColors);
camembert2.getStyler().setLegendVisible(false);
camembert2.getStyler().setPlotBorderVisible(false);
camembert2.getStyler().setChartTitleVisible(false);
camembert2.getStyler().setChartTitleBoxVisible(false);
camembert2.getStyler().setChartPadding(0);
camembert2.getStyler().setChartTitlePadding(0);
camembert2.getStyler().setBorderWidth(3);
camembert2.getStyler().setAnnotationsFont(new Font("Arial", Font.BOLD, 10));
camembert2.getStyler().setAnnotationsFontColor(Color.WHITE);
camembert2.addSeries("Item 1", 9);
camembert2.addSeries("Item 2", 10);
camembert2.addSeries("Item 3", 23);
camembert2.addSeries("Item 4", 58);
return camembert2;
}
Does anyone have any experience in an equivalent development ? Or does anybody know why the PDF is empty?
Thanks and regards,
Thomas.

Related

Page Content not Erasing with Rectangle fill in pdfbox

I am working on a requirement that , I need to mask the certain content based on Keys. With the PDF Rectangle fill i am able to mask well. But the user still able to get the content from masked region by selecting the text. How can i get rid of it.
PDDocument document = new PDDocument();
for (int i=0; i<1; i++) {
PDPage blankPage = new PDPage();
document.addPage( blankPage );
PDPageContentStream contentStream = new PDPageContentStream(document, document.getPage(0));
contentStream.beginText();
contentStream.setFont(PDType1Font.TIMES_ROMAN, 12);
contentStream.newLineAtOffset(25, 500);
String text = "This is the sample document and we are adding content to it.";
contentStream.showText(text);
contentStream.endText();
contentStream.setNonStrokingColor(Color.RED);
contentStream.addRect(25, 500, 100, 100);
contentStream.fill();
contentStream.close();
}
document.save("C:/PdfBox_Examples/my_doc.pdf");
System.out.println("PDF created");
document.close();

PDFBox Button execute javascript to close document

My use case is to have a button like so on a pdf page (really to add them to existing pages but for now I just want to see it work on anything).
----------
- Back -
----------
And what it does is just closes the current pdf page. The idea is to have multiple tabs opened and each tab is a pdf and then when you hit the "Back" button it closes the current pdf which will then focus back to the previous pdf. This is what I have been trying to use so far.
// Create a new empty document
try {
PDDocument document = new PDDocument();
// Create a new blank page and add it to the document
PDPage blankPage = new PDPage();
document.addPage( blankPage );
PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary();
borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
PDColor green = new PDColor(new float[] { 0, 1, 0 }, PDDeviceRGB.INSTANCE);
// PDAnnotationTextMarkup txtMark = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
// textWidth = (font.getStringWidth("Click Here") / 1000) * 18;
PDAnnotationLink txtLink = new PDAnnotationLink();
txtLink.setBorderStyle(borderULine);
// add an action
// PDActionURI action = new PDActionURI();
// action.setURI("www.google.com");
PDActionJavaScript action = new PDActionJavaScript("this.closeDoc()");
txtLink.setAction(action);
txtLink.setContents("HI");
txtLink.setColor(green);
PDRectangle position = new PDRectangle();
position.setLowerLeftX(10);
position.setLowerLeftY(20);
position.setUpperRightX(100);
position.setUpperRightY(40);
txtLink.setRectangle(position);
txtLink.setInvisible(false);
blankPage.getAnnotations().add(txtLink);
// Save the newly created document
document.save("C:\\Users\\jsmith\\Desktop\\demo\\BlankPage.pdf");
document.close();
} catch (IOException e) {
e.printStackTrace();
}
And I cant seem to see anything on the pdf page (its just all white), I did get the following code at at least be able to go to a new page instead of the javascript but it was still invisible. I just was able to hover over the bottom left and notice i could click on a link.
PDActionURI action = new PDActionURI();
action.setURI("www.google.com");
Improved answer as discussed in the comments of the OPs own answer, and it also includes the answer from the follow-up question.
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
COSDictionary acroFormDict = new COSDictionary();
PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
doc.getDocumentCatalog().setAcroForm(acroForm);
acroForm.setFields(new ArrayList<>());
PDPushButton button = new PDPushButton(acroForm);
button.setPartialName("Btn1");
PDActionJavaScript actionJavaScript = new PDActionJavaScript("this.closeDoc();");
PDAnnotationAdditionalActions additionalActions = new PDAnnotationAdditionalActions();
additionalActions.setU(actionJavaScript);
// widget
PDAnnotationWidget widget = button.getWidgets().get(0);
widget.setActions(additionalActions);
widget.setRectangle(new PDRectangle(100, 700, 100, 50));
PDColor colourBlack = new PDColor(new float[] { 0, 0, 0 }, PDDeviceRGB.INSTANCE);
PDAppearanceCharacteristicsDictionary fieldAppearance
= new PDAppearanceCharacteristicsDictionary(new COSDictionary());
fieldAppearance.setBorderColour(colourBlack);
widget.setAppearanceCharacteristics(fieldAppearance);
// Create appearance
PDAppearanceDictionary appearanceDictionary = new PDAppearanceDictionary();
PDAppearanceStream appearanceStream = new PDAppearanceStream(doc);
appearanceStream.setResources(new PDResources());
try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream))
{
PDRectangle bbox = new PDRectangle(widget.getRectangle().getWidth(), widget.getRectangle().getHeight());
appearanceStream.setBBox(bbox);
cs.setNonStrokingColor(0, 0, 0); // black
cs.addRect(bbox.getLowerLeftX() + 0.5f, bbox.getLowerLeftY() + 0.5f, bbox.getWidth() - 1, bbox.getHeight() - 1);
cs.stroke();
// put some useful text
cs.setFont(PDType1Font.HELVETICA, 20);
cs.beginText();
cs.newLineAtOffset(20, 20);
cs.showText("Close");
cs.endText();
}
appearanceDictionary.setNormalAppearance(appearanceStream);
widget.setAppearance(appearanceDictionary);
page.getAnnotations().add(widget);
acroForm.getFields().add(button);
doc.save("..../Button.pdf");
doc.close();

Can't generate PDF with ITEXT in packaged Javafx or jar executable

This problem has been choking me for quite some time now precisely more than a month now.i tried developing a small Javafx application and I used ITEXT 5.3 version and everything works just fine where i used icepdf for displaying the generated PDF in netbean.perfectly works fine in netbeans .But once I tried running the executable jar program outside netbean it does not generate the PDF.i tried packaging it using advanced installer and the pdf did not generate too.I tried some solutions with this pdf not generated by itext library from java application but it didn't help.
Every assistance would be truly appreciated
Here is my source code for the PDF generation:
#FXML
private void generatereportforresistance(ActionEvent event) throws IOException {
XYSeries powerSeries = new XYSeries("Power_Speed relation");
for (double i=0;i<getValue(13);i=i+0.01){
double p=getPower(i)*0.51444;
powerSeries.add(i, p);
}
XYDataset xyDataset = new XYSeriesCollection(powerSeries);
JFreeChart chart = ChartFactory.createXYLineChart(
"Effective Power V.S Speed", "Speed[knots]", "Power[KW]", xyDataset,
PlotOrientation.VERTICAL, true, true, true);
//Render the frame
ChartFrame chartFrame = new ChartFrame("Power V.S speed Charts", chart);
chartFrame.setIconImage(Toolkit.getDefaultToolkit().getImage("app_icon.png"));
//chartFrame.setVisible(true);
//chartFrame.setSize(800, 800);
StandardChartTheme st = (StandardChartTheme)org.jfree.chart.StandardChartTheme.createJFreeTheme();
st.setTitlePaint(Color.decode("#4572a7"));
st.setRangeGridlinePaint( Color.decode("#C0C0C0"));
st.setPlotBackgroundPaint( Color.white );
st.setChartBackgroundPaint( Color.white );
st.setGridBandPaint( Color.red );
st.setAxisLabelPaint( Color.decode("#666666") );
st.apply( chart );
double a_aa = r_a(getValue(14),getValue(13),getValue(17),getValue(2),getValue(18),getValue(0),getValue(3),getValue(8),getValue(7),getValue(9),getValue(10));
double b_bb=r_tr(getValue(13),getValue(14),getValue(11),getValue(2),getValue(10));
double c_cc=r_b(getValue(13),getValue(14),getValue(7),getValue(3),getValue(10),getValue(2),getValue(8),getValue(16));
double d_dd=r_w(getValue(13),getValue(14),getValue(7),getValue(5),getValue(11),getValue(3),getValue(18),getValue(10),getValue(6),getValue(17),getValue(0),getValue(9),getValue(2),getValue(8),getValue(16));
double e_ee=r_app(getValue(14),getValue(13),getValue(0),getValue(15),getValue(12));
double f_ff=r_f(getValue(14),getValue(13),getValue(0),getValue(15),getValue(2),getValue(10),getValue(17),getValue(7),getValue(18),getValue(9),getValue(6));
double totoal =f_ff+a_aa+b_bb+c_cc+d_dd+e_ee;
double p_e =totoal *getValue(13)*0.51444;
double p_s =p_e/getValue(19);
//double values of parameters para = new
double[] val = new double[9];
val[0]=a_aa; val[1]=b_bb; val[2]=c_cc; val[3]=d_dd; val[4]=e_ee; val[5]=f_ff; val[6]=totoal; val[7]=p_e; val[8]=p_s;
//string values of units and parameters namings
String [] para = new String[9];
para[0]="Model_Ship Correlation Resistance";para[1]="Additional Pressure Resisitance of immersed Transom";para[2]="Additional pressure resistance of bulbous bow near water surface";
para[3]="Wave Resistance";para[4]="Resistance due to Appendages";para[5]="Frictional resistance";para[6]="Total resistance";
para[7]="Effective Power";para[8]="Shaft Power";
String [] units = new String[9];
units[0]="KN"; units[1]="KN"; units[1]="KN"; units[2]="KN"; units[3]="KN"; units[4]="KN"; units[5]="KN"; units[6]="KN"; units[7]="KW"; units[8]="KW";
//generating the report
PdfWriter wr = null;
Document doc = new Document();
try{
//fos = new FileOutputStream(new File(filename));
PdfPTable table = new PdfPTable(new float[] { 3, 2, 1 });
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell("Resistance and Powering parameter");
table.addCell("Values");
table.addCell("Units");
table.setHeaderRows(1);
PdfPCell[] cells = table.getRow(0).getCells();
for (int j=0;j<cells.length;j++){
cells[j].setBackgroundColor(BaseColor.GRAY);
}
for (int i=0;i<9;i++){
table.addCell(new PdfPCell(new Paragraph(String.valueOf(para[i]))));
table.addCell(new PdfPCell(new Paragraph(String.valueOf(val[i]))));
table.addCell(new PdfPCell(new Paragraph(String.valueOf(units[i]))));
}
wr=PdfWriter.getInstance(doc, new FileOutputStream("report.pdf"));
doc.open();
Image in = Image.getInstance("app_icon.png");
in.scaleToFit(100,100);
//in.setAbsolutePosition(500,500);
doc.add(in);
doc.addTitle("Resistance and powering report");
doc.addCreationDate();
float w =520;//PageSize.A4.getWidth();
float h =380;//*PageSize.A4.getHeight();
//doc.add(new Paragraph("Resistance and powering report",FontFactory.getFont(FontFactory.TIMES_BOLD, 19,Font.BOLD,BaseColor.RED)));
//doc.add(new Paragraph(new Date().toString()));
doc.add(new Paragraph("Resistance and powering report",FontFactory.getFont(FontFactory.TIMES_ROMAN,18,Font.BOLD,BaseColor.ORANGE)));
doc.add(new Paragraph(new Date().toString()));
doc.add(new Paragraph("**********************************************************************************************"));
doc.add(table);
//doc.newPage();
doc.add(new Paragraph("The effective power graph against the speed is shown below",FontFactory.getFont(FontFactory.TIMES_ITALIC,14,Font.ITALIC)));
PdfContentByte tem = wr.getDirectContent();
PdfTemplate tl = tem.createTemplate(w,h);
Graphics2D gd =new PdfGraphics2D(tl,w,h,new DefaultFontMapper());
Rectangle2D r = new Rectangle2D.Double(0,0,w,h);
chart.draw(gd, r);
gd.dispose();
Image im = Image.getInstance(tl);
doc.add(im);
/*Image inm = Image.getInstance("app_icon.png");
in.setAbsolutePosition(490,100);
wr.getDirectContent().addImage(in);
doc.add(inm);*/
doc.close(); }catch(Exception ex){
}
try{
SwingController con= new SwingController();
SwingViewBuilder fac = new SwingViewBuilder(con);
JPanel jp =fac.buildViewerPanel();
con.getDocumentViewController().setAnnotationCallback(
new org.icepdf.ri.common.MyAnnotationCallback(con.getDocumentViewController()));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(jp);
con.openDocument("report.pdf");
frame.setIconImage(Toolkit.getDefaultToolkit().getImage("app_icon.png"));
frame.pack();
frame.setVisible(true);
}
catch(Exception ex){
ex.printStackTrace();
}
// Desktop.getDesktop().open(new File("report.pdf"));
}
Well, i know it's an older question but for those who struggle with this problem. Execute your jar file on the therminal with the command java -jar YouJarFile.jar and look what the problem is. For me the problem was that i saved the file on an relativ path. When i changed the location to an absolute path the problem for me was solved.

PDF-Checkbox - check one and uncheck another without JavaScript

in my project I need 3 checkboxes which should work like radiobuttons. But radiobuttons have some drawbacks with appearance in Adobe Reader. For this reason I have to use checkboxes. There is a very interesting answer, but I don't understand how this can be done with iText:
Java iText and custom Radiobutton behaviour
Can anybody -- especially Lonzak, the author of this posting -- help me in this case. Thanks and Kind regards, Dirk
I think the solution is to fix your current code. The following example creates 3 radiobuttons and all contain a cross. It was based on itext 5 and you may have to adapt it a bit for itext 7.
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
document.open();
RadioCheckField bt = new RadioCheckField(writer, new Rectangle(261, 576, 279, 594), "radio", "value1");
bt.setCheckType(RadioCheckField.TYPE_CROSS);
bt.setBackgroundColor(BaseColor.WHITE);
//bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
bt.setBorderColor(BaseColor.BLACK);
bt.setTextColor(BaseColor.BLACK);
bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
bt.setChecked(false);
PdfFormField f1 = bt.getRadioField();
bt.setOnValue("value2");
bt.setChecked(true);
bt.setBox(new Rectangle(287, 577, 305, 595));
PdfFormField f2 = bt.getRadioField();
bt.setChecked(false);
PdfFormField top = bt.getRadioGroup(true, false);
bt.setOnValue("value3");
bt.setBox(new Rectangle(314, 578, 332, 596));
PdfFormField f3 = bt.getRadioField();
top.addKid(f1);
top.addKid(f2);
top.addKid(f3);
writer.addAnnotation(top);
document.close();
Update: Here is your code with iText7 however there seems to be a bug so that the check style is not changed for radiobuttons. Maybe the itext guys can say more...
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output7.pdf"));
Document doc = new Document(pdfDoc);
PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "ExampleGroup", "");
radioGroup.setPage(1);
pdfDoc.addNewPage();
PdfFormField field1 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(261, 576, 18, 18), radioGroup, "value1");
field1.setCheckType(PdfFormField.TYPE_CROSS);
field1.setValue("value1");
field1.regenerateField();
PdfFormField field2 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(287, 577, 18, 18), radioGroup, "value2");
field2.setCheckType(PdfFormField.TYPE_CROSS);
field2.regenerateField();
PdfFormField field3 = PdfFormField.createRadioButton(pdfDoc, new Rectangle(314, 578, 18, 18), radioGroup, "value3");
field3.setCheckType(PdfFormField.TYPE_CROSS);
field3.regenerateField();
PdfAcroForm.getAcroForm(pdfDoc, true).addField(radioGroup);
doc.close();
Final solution with iText 7:
public static void main(String[] args) throws Exception {
// RadioButton with cross instead of bullet.
final String filename = "SampleRadioButton.pdf";
final float boxLength = 20;
final float crossWidth = 1;
final String[] languages = { "Dutch", "English", "French" };
try (PdfWriter writer = new PdfWriter(filename); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) {
pdfDoc.addNewPage();
final PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
final PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdfDoc, "Language", languages[1]);
int count = 0;
for (final String language : languages) {
count++;
// button
final Rectangle rect = new Rectangle(40, 800 - (count * 30), boxLength, boxLength);
final PdfFormField radioButton = PdfFormField.createRadioButton(pdfDoc, rect, radioGroup, language);
final PdfDictionary radioDict = radioButton.getPdfObject();
final PdfDictionary mk = new PdfDictionary();
mk.put(PdfName.CA, new PdfString("8")); // check=4, circle=1, cross=8, diamond=u, square=n, star=H
radioDict.put(PdfName.MK, mk);
radioButton.setVisibility(PdfFormField.VISIBLE);
editAppearance(pdfDoc, radioButton, language, boxLength, crossWidth);
// text
final Paragraph para = new Paragraph(language).setFontSize(18);
doc.showTextAligned(para, 70, 800 - (count * 30), TextAlignment.LEFT);
}
form.addField(radioGroup);
}
Desktop.getDesktop().open(new File(filename));
}
private static void editAppearance(PdfDocument pdfDoc, PdfFormField radioButton, String value, float length, float crossWidth) {
final PdfStream streamOn = (PdfStream) new PdfStream().makeIndirect(pdfDoc);
final PdfCanvas canvasOn = new PdfCanvas(streamOn, new PdfResources(), pdfDoc);
final Rectangle rect = new Rectangle(0, 0, length, length);
final PdfFormXObject xObjectOn = new PdfFormXObject(rect);
canvasOn.saveState();
canvasOn.setStrokeColor(ColorConstants.BLACK).setLineWidth(crossWidth);
// bottom left to top right
canvasOn.moveTo(0, 0).lineTo(length, length).stroke();
// Top left to bottom right
canvasOn.moveTo(0, length).lineTo(length, 0).stroke();
canvasOn.restoreState();
xObjectOn.getPdfObject().getOutputStream().writeBytes(streamOn.getBytes());
final PdfWidgetAnnotation widget = radioButton.getWidgets().get(0);
widget.setNormalAppearance(new PdfDictionary());
widget.getNormalAppearanceObject().put(new PdfName(value), xObjectOn.getPdfObject());
}
}

IText Stamper undeline specific text

I'm trying to do a report from a java swing application, I tried jasper reports and other tools, but I don't understand how to use them properly.
I gave a try to itext, and I actually have something like this.
public void createPDF(){
try {
PdfReader reader = new PdfReader("pdf/watermark.pdf"); // input PDF
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream("C:\\Users\\FIREFENIX\\Documents\\NetBeansProjects\\Java\\PDFCreator\\src\\pdf\\watermarkFinal.pdf")); // output PDF
BaseFont bfArialPlain = BaseFont.createFont("/font/arial.ttf",BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
BaseFont bfArialBold = BaseFont.createFont("/font/arialbd.ttf",BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
BaseFont bfArialBlack = BaseFont.createFont("/font/ariblk.ttf",BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
for (int i=1; i<=reader.getNumberOfPages(); i++){
PdfContentByte over = stamper.getOverContent(i);
//TOP LEFT
over.beginText();
over.setFontAndSize(bfArialBold, 9);
over.setTextMatrix(040, 670);
over.showText("Registry Date: "); //<-----That field/line/text
over.endText();
over.beginText();
over.setFontAndSize(bfArialPlain, 9);
over.setTextMatrix(115, 670);
over.showText("21/07/2016");
over.endText();
over.beginText();
over.setFontAndSize(bfArialBold, 9);
over.setTextMatrix(040, 660);
over.showText("Validation Date: "); //<-----And that one
over.endText();
over.beginText();
over.setFontAndSize(bfArialPlain, 9);
over.setTextMatrix(115, 660);
over.showText("21/07/2016");
over.endText();
//TOP RIGHT...
//...
//...
}
File myFile = new File("C:\\Users\\FIREFENIX\\Documents\\NetBeansProjects\\Java\\PDFCreator\\src\\pdf\\watermarkFinal.pdf");
Desktop.getDesktop().open(myFile);
//////////PRINT DISABLED////////Desktop.getDesktop().print(myFile);
stamper.close();
reader.close();
} catch (IOException | DocumentException ex) {
Logger.getLogger(PDFCreator.class.getName()).log(Level.SEVERE, null, ex);
}
}
I need to have thoose 2 lines underlined.
How can I do it?
There is any other way I can do this easyer?
Thanks.
You are using the very difficult way to add content. There's a much easier way as explained in the official documentation: How to add text at an absolute position on the top of the first page?
Instead of:
cb.BeginText();
cb.MoveText(700, 30);
cb.SetFontAndSize(bf, 12);
cb.ShowText("My status");
cb.EndText();
Use:
ColumnText ct = new ColumnText(stamper.getOverContent(i));
ct.setSimpleColumn(new Rectangle(30, 600, 523, 720));
ct.addElement(new Paragraph("My status"));
ct.go();
If you want to underline text, you need to use a Chunk as is done in this FAQ entry: Strikethrough in cell using itext in Android/Java
So let's adapt the previous snippet:
ColumnText ct = new ColumnText(stamper.getOverContent(i));
ct.setSimpleColumn(new Rectangle(30, 600, 523, 720));
Chunk c = new Chunk("Underlined text");
c.setUnderline(1.5f, -1);
ct.addElement(new Paragraph(c));
ct.go();
For more info, see Absolute positioning of text and the search results for underline.

Categories