I am trying to create a string by arranging my data in two columns.
String s = "";
List selectedItems = listView.getSelectionModel().getSelectedItems();
s = s + (String) selectedItems.get(0);
String t;
for (int i = 1 ; i<selectedItems.size();i++){
t = (String) selectedItems.get(i);
if (i%2!=0){
s = s + "\t\t\t";
}
else{
s = s + "\n";
}
s = s + (String) t;
}
My idea is to use a code like this for the task. but depending on the length of the strings, I can't get the second column to one line.
I am thinking there is a way to count the number of tabs need to cover one string an change the number of extra tabs I add instead of adding 3 tabs to every line. but I can't figure out how to count this.
how can I fix this problem?
current results:
one two
three four
five six
expected results:
one two
three four
five six
this is the result of after fill the string with " " with a total length of 30.
i am only using jfx to get the data. itextPdf us used to write the string to a pdf
Accordin to this document you have 3 options:
Assuming you have such data:
public static final String[][] DATA = {
{"John Edward Jr.", "AAA"},
{"Pascal Einstein W. Alfi", "BBB"},
};
1: use a table
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(50);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
table.setWidths(new int[]{5, 1});
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.addCell("Name: " + DATA[0][0]);
table.addCell(DATA[0][1]);
table.addCell("Surname: " + DATA[1][0]);
table.addCell(DATA[1][1]);
table.addCell("School: " + DATA[2][0]);
table.addCell(DATA[1][1]);
document.add(table);
document.close();
}
2: use tabs
public void createPdf(String dest) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
document.add(createParagraphWithTab("Name: ", DATA[0][0], DATA[0][1]));
document.add(createParagraphWithTab("Surname: ", DATA[1][0], DATA[1][1]));
document.add(createParagraphWithTab("School: ", DATA[2][0], DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithTab(String key, String value1, String value2) {
Paragraph p = new Paragraph();
p.setTabSettings(new TabSettings(200f));
p.add(key);
p.add(value1);
p.add(Chunk.TABBING);
p.add(value2);
return p;
}
3: use spaces and a monospaced font
public void createPdf(String dest) throws DocumentException, IOException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Name", DATA[0][0]), DATA[0][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Surname", DATA[1][0]), DATA[1][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "School", DATA[2][0]), DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithSpaces(Font font, String value1, String value2) {
Paragraph p = new Paragraph();
p.setFont(font);
p.add(String.format("%-35s", value1));
p.add(value2);
return p;
}
To achieve the desired output you don't need to count anything - you just use System.out.printf:
public class Main {
public static void main(String[] args) {
System.out.printf("%-10s %-10s\n", "test", "test1");
System.out.printf("%-10s %-10s\n", "longertest", "test2");
}
}
Result:
test test1
longertest test2
As was mentioned in the comment - that will not fix a problem if the font that you use is not monospaced, so I would suggest changing the font as well.
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);
Related
I have a question while using itext7. I want to generate a pdf by generating a QR code.
There is no problem with normal creation. However, I want to adjust the size of the dots of the QR.
I don't want to reduce the overall size of the QR code, I just want to reduce the size of the dots in it.
Currently, only the overall size of the QR code can be adjusted.
public class PdfTest {
public static final String DEST = "D:\\output.pdf";
public static final String SRC = "D:\\202106003196.pdf";
static PdfDocument mPdfDocument;
public static void main(String[] args) {
try {
File file = new File(DEST);
file.getParentFile().mkdirs();
FontProgramFactory.registerFont("D:\\font\\MAISONNEUEEXT-MEDIUM.OTF", "MAISONNEUEEXT-MEDIUM");
PdfFont mPdfFont_MAISONNEUEEX_MEDIUM = PdfFontFactory.createRegisteredFont("MAISONNEUEEXT-MEDIUM");
mPdfDocument = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
Document mDocument = new Document(mPdfDocument);
// QR
addQR("HTTP://QR.TEST.COM/0123456", mPdfDocument, 1, 25, 50);
PdfPage pdfPage = mPdfDocument.getPage(1);
Rectangle pageSize = pdfPage.getPageSize();
Rectangle[] mRectangle = {new Rectangle(0, 10, pageSize.getRight(), 50)};
mDocument.setRenderer(new ColumnDocumentRenderer(mDocument, mRectangle));
mDocument.close();
mPdfDocument.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void addQR(String mQRCode, PdfDocument mPdfDocument, int mPage, float mX, float mY) {
PdfPage mPdfPage = mPdfDocument.getPage(mPage);
BarcodeQRCode mBarcodeQRCode;
Map<EncodeHintType, Object> mHints = new HashMap<>();
mHints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
mHints.put(EncodeHintType.MIN_VERSION_NR, 2);
mBarcodeQRCode = new BarcodeQRCode(mQRCode, mHints);
PdfCanvas over = new PdfCanvas(mPdfPage);
mBarcodeQRCode.placeBarcode(over, ColorConstants.RED, 0.5f);
}
}
enter image description here
The size of dots is defined by QR-algorithm itself and depends on the length of the content. Let me modify your code to demonstrate it.
In the snippet below we will add 10 QR codes: the first one will represent just one "Lorem ipsum" sentence, the last one - 10 sentences.
#Test
public void barcodesTest() throws FileNotFoundException {
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "barcodes.pdf"));
String text = "Lorem ipsum dolor sit amet";
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10; i++) {
pdfDocument.addNewPage();
builder.append(text);
addQR(builder.toString(), pdfDocument, i+1);
}
pdfDocument.close();
}
private static void addQR(String text, PdfDocument pdfDoc, int pageNumber) {
PdfPage page = pdfDoc.getPage(pageNumber);
Map<EncodeHintType, Object> mHints = new HashMap<>();
mHints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
mHints.put(EncodeHintType.MIN_VERSION_NR, 2);
BarcodeQRCode qrCode = new BarcodeQRCode(text, mHints);
PdfCanvas over = new PdfCanvas(page);
// 12 is passed to make the qr code appear big
qrCode.placeBarcode(over, ColorConstants.RED, 12);
}
If we compare the barcodes, we will see that the size of the dots is reduced gradually page by page (in fact, the barcode on the last page is so huge, that it occupies far more space than the page itself):
The first page:
The last page:
Hi I am trying to create an PDF using itextpdf.
It is working fine when tested locally.
But after aws deployment I am getting 406 Not Acceptable with java.io.IOException: The document has no pages excpetion.
Many answers are there but those are not related to deployment issues.
Do I need to check any network configuration or problem lies in the pdf generation code?
Following is my code implementation:
Please suggest some solution.
public byte[] createPdf(List<Participant> participantList) throws IOException,
DocumentException, com.google.zxing.WriterException {
Document document = new Document();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
document.open();
document.add(createMainTable(participantList));
document.close();
return byteArrayOutputStream.toByteArray();
}
public static PdfPTable createMainTable(List<Participant> optionalParticipant) throws BadElementException,
IOException, com.google.zxing.WriterException {
PdfPTable table = new PdfPTable(2);
logger.info("Main Table was created");
for (int i = 0; i < optionalParticipant.size(); i++) {
PdfPCell cell1 = new PdfPCell();
cell1.setBorderWidth(0);
cell1.setPadding(10f);
cell1.addElement(createSubTable(optionalParticipant.get(i)));
table.addCell(cell1);
}
return table;
}
public static PdfPTable createSubTable(Participant participant) throws BadElementException,
IOException, com.google.zxing.WriterException {
BaseColor baseColor = new BaseColor(150, 150, 150);
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
PdfPCell cell, cell1, cell2;
Font font = new Font();
font.setSize(10f);
font.setColor(BaseColor.WHITE);
String participantName = participant.getFirstName() + " " + participant.getLastName();
Chunk chunk = new Chunk(participantName, font);
Paragraph head = new Paragraph(" "+chunk);
head.setFont(font);
cell = new PdfPCell(head);
cell.setColspan(2);
cell.setBackgroundColor(baseColor);
cell.setPadding(2f);
table.addCell(cell);
String qrData = participant.getQrCodeData();
Image img = getQRCodeImage(qrData);
font = new Font();
font.setSize(5f);
chunk = new Chunk("\n" + "Event ID: " + participant.getEvent().getEventId() +
"\n\n" + "Unique ID: " + participant.getUniqueId() +
"\n\n" + "Email ID: " + participant.getEmail(), font);
Paragraph body = new Paragraph(chunk);
cell1 = new PdfPCell(body);
cell1.setBorderWidthRight(0);
cell1.setPadding(10f);
cell2 = new PdfPCell();
cell2.addElement(img);
cell2.setBorderWidthLeft(1);
cell2.setPadding(10f);
table.addCell(cell1);
table.addCell(cell2);
logger.info("Sub Table was created");
return table;
}
Please check participantList is not null and contains elements. You can use logger to print size of list before start using it.
logger.info("No of participants: "+participantList.size());
Also, Immediately after opening document, always add an empty chunk to document so that you can avoid this exception.
document.open();
document.add(new Chunk(""));
I tried to add a blank cell with space (" ") into my pdf file. i.e
PdfPCell blankCell = ContentHandler.getNormalCell(" ", language,fontsize);
It throws this error
Message: java.lang.NullPointerException
com.itextpdf.text.DocumentException: java.lang.NullPointerException
at com.itextpdf.text.pdf.PdfDocument.add(PdfDocument.java:727)
at com.itextpdf.text.Document.add(Document.java:282)
Then i removed space from cell.. i.e
PdfPCell blankCell = ContentHandler.getNormalCell("", language,fontsize);
I resolved my issue this way but pdf is in bad beauty.
Can somebody help me out with, is there any solution available for this, apart from what i am doing
Edited:
public static PdfPCell getNormalCell(String string, String language, float size) throws DocumentException, IOException {
// TODO Auto-generated method stub
Font f = new Font();
if(string!=null && !"".equals(string)){
f = getFontForThisLanguage(language);
}
if(size==-1) //Using a condition to make color RED as per need in view report
{
f.setColor(BaseColor.RED);
}
f.setSize(size);
Chunk chunk = new Chunk(new String(string.getBytes(), "UTF-8"),f);
PdfPCell pdfCell1 = new PdfPCell(new Phrase(string, f));
pdfCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
return pdfCell1;
}
First the answer to your question: I have created an example called CellMethod and I can perfectly add a " " to a PdfPCell without causing a NullPointerException. This is my code:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.addCell("Winansi");
table.addCell(getNormalCell("Test", null, 12));
table.addCell("Winansi");
table.addCell(getNormalCell("Test", null, -12));
table.addCell("Greek");
table.addCell(getNormalCell("\u039d\u03cd\u03c6\u03b5\u03c2", "greek", 12));
table.addCell("Czech");
table.addCell(getNormalCell("\u010c,\u0106,\u0160,\u017d,\u0110", "czech", 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", null, 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", "greek", 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", "czech", 12));
document.add(table);
document.close();
}
public static PdfPCell getNormalCell(String string, String language, float size)
throws DocumentException, IOException {
if(string != null && "".equals(string)){
return new PdfPCell();
}
Font f = getFontForThisLanguage(language);
if(size < 0) {
f.setColor(BaseColor.RED);
size = -size;
}
f.setSize(size);
PdfPCell cell = new PdfPCell(new Phrase(string, f));
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
return cell;
}
public static Font getFontForThisLanguage(String language) {
if ("czech".equals(language)) {
return FontFactory.getFont(FONT, "Cp1250", true);
}
if ("greek".equals(language)) {
return FontFactory.getFont(FONT, "Cp1253", true);
}
return FontFactory.getFont(FONT, null, true);
}
The resulting PDF can be found here: cell_method.pdf
Now about the comments. It's as if you don't want to accept that your code is badly written. Instead, you claim that there's a problem with iText. It is a bad craftsman who blames his tools.
You did an attempt to improve your method, but let's take a look at your method and add some comments:
public static PdfPCell getNormalCell(String string, String language, float size)
throws DocumentException, IOException {
// The next line will create an instance of Helvetica, 12pt.
Font f = new Font();
// I don't understand this check. Why is it important to check string here?
if(string!=null && !"".equals(string)){
// are you sure you didn't want to check if language is not null?
f = getFontForThisLanguage(language);
// we have no idea what getFontForThisLanguage is doing
// what if language is null, does it throw an exception?
}
// This is ridiculous. See the next comment to find out why
if(size==-1) //Using a condition to make color RED as per need in view report
{
f.setColor(BaseColor.RED);
}
// In some situations, you are setting the font size to -1, that doesn't make sense
f.setSize(size);
// This line doesn't make sense either.
// (1.) string should already be in unicode.
// why are you getting the bytes and creating a UTF-8 string?
// (2.) why are you creating this chunk object? you never use it
Chunk chunk = new Chunk(new String(string.getBytes(), "UTF-8"),f);
// See: you're creating a Phrase with string, you don't use chunk!
PdfPCell pdfCell1 = new PdfPCell(new Phrase(string, f));
pdfCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
return pdfCell1;
}
Please compare with my version of the method.
I'm trying to generate a pdf file using iText.
The file gets produced just fine, but I can seem to use special characters like german ä, ö, ...
The sentence I want to be written is (for example)
■ ...ä...ö...
but the output is
■...ä...ö...
(I had to kind of blur the sentences, but I guess you see what I'm talking about...)
Somehow this black block-thing and all "Umlaute" can't be generated ...
The font used is the following:
private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12,
Font.BOLD);
So there should be no problem about the font not having these characters...
I'm using IntelliJ Idea to develop, the encoding of the .java file is set to UTF-8, so there should be no problem too...
I'm kind of lost here; does anyone know what i may do to get it working?
Thanks in advance and greetz
gilaras
---------------UPDATE---------------
So here's (part of) the code:
#Controller
public class Generator {
...
Font font = new Font(Font.FontFamily.TIMES_ROMAN, 9f, Font.BOLD);
...
Paragraph intro = new Paragraph("Ich interessiere mich für ...!", font_12_bold);
Paragraph wantContact = new Paragraph("■ Ich hätte gerne ... ", font);
...
Phrase south = new Phrase("■ Süden □ Ost-West ...");
...
#RequestMapping(value = "/generatePdf", method = RequestMethod.POST)
#ResponseBody
public String generatePdf(HttpServletRequest request) throws IOException, DocumentException, com.lowagie.text.DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(FILE));
addMetaData(document);
document.open();
addContent(document, request);
document.add(new Paragraph("äöü"));
document.close();
return "";
}
private void addContent(Document document, HttpServletRequest request)
throws DocumentException {
Paragraph preface = new Paragraph();
preface.setAlignment(Element.ALIGN_JUSTIFIED);
addEmptyLine(preface, 1);
preface.add(new Paragraph("Rückantwort", catFont));
addEmptyLine(preface, 2);
preface.add(intro);
addEmptyLine(preface, 1);
if (request.getParameter("dec1").equals("wantContact")) {
preface.add(wantContact);
} else {
...
}
document.add(preface);
}
private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
private static void addMetaData(Document document) {
document.addTitle("...");
document.addSubject("...");
document.addKeywords("...");
document.addAuthor("...");
document.addCreator("...");
}
}
I had to take some things out, but I kept some Umlaut-character and other special characters, so that you can see, where the problem occurs ... :-)
You might want to try and embed the font using this technique:
BaseFont times = BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(times, 12, Font.BOLD);
Does anyone know an easy way to include the greater than or equal symbol in an iText PDF document without resorting to custom fonts?
You need to add the unicode for this character. Also make sure that the char is included in the font you use.
document.add( new Paragraph("\u2265"));
Use the below code for the same. It's work for me.
//symbol for greater or equal then
public void process() throws DocumentException, IOException {
String dest = "/home/ashok/ashok/tmp/hello.pdf";
BaseFont bfont = BaseFont.createFont(
"/home/ashok/ashok/fonts/Cardo-Regular.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
Font font = new Font(bfont, 12);
try {
Document document=new Document();
PdfWriter.getInstance(document,new
FileOutputStream("/home/ashok/ashok/tmp/hello.pdf"));
document.open();
Chunk chunk = new Chunk("\u2265");
Paragraph p = new Paragraph("Mathematical Operators are ",font);
p.add(chunk);
document.add(p);
p = new Paragraph(" ",font);
chunk = new Chunk("\u2264");
p.add(chunk);
document.add(p);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}