I am trying to convert a .txt file into a .pdf file using iText library.
The problem that I am facing is the following:
I have a clear formatting in the txt file, something similar with this:
TEXT *******************
Other text here * SOME_CODE_HERE_ *
Other text *******************
And in the output the formatting is gone and looks like this:
TEXT ******************
Other text here * SOME_CODE_HERE_ *
Other text ******************
The code looks like this:
public static boolean convertTextToPDF(File file) throws Exception {
BufferedReader br = null;
try {
Document pdfDoc = new Document(PageSize.A4);
String output_file = file.getName().replace(".txt", ".pdf");
System.out.println("## writing to: " + output_file);
PdfWriter.getInstance(pdfDoc, new FileOutputStream(output_file)).setPdfVersion(PdfWriter.VERSION_1_7);;
pdfDoc.open();
Font myfont = new Font();
myfont.setStyle(Font.NORMAL);
myfont.setSize(11);
pdfDoc.add(new Paragraph("\n"));
if (file.exists()) {
br = new BufferedReader(new FileReader(file));
String strLine;
while ((strLine = br.readLine()) != null) {
Paragraph para = new Paragraph(strLine + "\n", myfont);
para.setAlignment(Element.ALIGN_JUSTIFIED);
pdfDoc.add(para);
}
} else {
System.out.println("no such file exists!");
return false;
}
pdfDoc.close();
}
catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null)
br.close();
}
return true;
}
I also tried to create a BaseFont with IDENTITY_H but it doesn't work.
I guess it's about the encoding or something like that.
What do you think? I run out of solutions...
Thanks
LE:
As suggested by Alan, and by the tutorial from iText's page, I used this part in addition with my existing code and it works fine.
BaseFont courier = BaseFont.createFont(BaseFont.COURIER, BaseFont.CP1252, BaseFont.EMBEDDED);
Font myfont = new Font(courier);
You need to use a Monospaced Font e.g. Courier.
http://en.wikipedia.org/wiki/Monospaced_font
http://itextpdf.com/examples/iia.php?id=208
I know this is old, but i had the same problem in converting text files into pdf's and i used this (i wrote this in vb.net):
Dim pdfDoc As Document = New Document(PageSize.A4)
Dim pdfWrite As PdfWriter = PdfWriter.GetInstance(pdfDoc, New FileStream(pdfFoldername & "\" & "name of file", FileMode.Create))
pdfDoc.Open()
Dim courier As BaseFont = BaseFont.CreateFont(BaseFont.COURIER, BaseFont.CP1252, BaseFont.EMBEDDED)
Dim myfont As iTextSharp.text.Font = New iTextSharp.text.Font(courier, 10)
Dim para As Paragraph = New Paragraph(page, myfont)
pdfDoc.Add(para)
The difference to the above answer and updated code is using '10' as my font size. That made the PDF look identical to the formatting from the text file.
In order to get beautiful result, you should use a PDF generating library supporting "Word-like" tabulation (left, right and center) by absolute position in points or percent.
Here I used PDFFlow library to move text to the exact position (for example, text "(Name)" is placed at the position 80% from left page side):
DocumentBuilder
.New()
.AddSection()
.AddParagraph()
// Create a line from X=0 to X=20%:
.AddTabSymbol().AddTabulationInPercent(20, TabulationType.Right, TabulationLeading.BottomLine)
// Create a line from X=60% to X=100%:
.AddTabSymbol().AddTabSymbol().AddTabulationInPercent(60).AddTabulationInPercent(100, TabulationType.Right, TabulationLeading.BottomLine)
.ToSection()
.AddParagraph()
// Add text under the first line in the center (position 10%):
.AddTabSymbol().AddTextToParagraph("(Date)").AddTabulationInPercent(10, TabulationType.Center)
// Add text under the second line in the center (position 80%):
.AddTabSymbol().AddTextToParagraph("(Name)").AddTabulationInPercent(80, TabulationType.Center)
.ToDocument().Build("Result.pdf");
You can also set tabulation in points. But in case you need to change PaperSize and Orientation dynamically, better to use percent, and the library will calculate position in points automatically.
Here is a tutorial with more examples: Adding Tabulation to PDF.
Related
I am using the code from the below link to render the images
MyImageRenderListener - IText
Below is my try block of the Code. What I am actually doing is finding the DPI of the image and if the dpi of the image is below 300 then writing it in a text file.
NOW, I also want to write the page numbers where these images are located in the PDF. How can I obtain the Page Number of that image?
try {
String filename;
FileOutputStream os;
PdfImageObject image = renderInfo.getImage();
BufferedImage img = null;
String txtfile = "results/results.txt";
PdfDictionary imageDict = renderInfo.getImage().getDictionary();
float widthPx = imageDict.getAsNumber(PdfName.WIDTH).floatValue();
float heightPx = imageDict.getAsNumber(PdfName.HEIGHT).floatValue();
float widthUu = renderInfo.getImageCTM().get(Matrix.I11);
float heigthUu = renderInfo.getImageCTM().get(Matrix.I22);
float widthIn = widthUu/72;
float heightIn = heigthUu/72;
float imagepdi = widthPx/widthIn;
filename = String.format(path, renderInfo.getRef().getNumber(), image.getFileType());
System.out.println(filename+"-->"+imagepdi);
if(imagepdi < 300){
File file = new File("C:/Users/Abhinav/workspace/itext/results/result.txt");
if(filename != null){
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
file.setReadable(true, false);
file.setExecutable(true, false);
file.setWritable(true, false);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(filename);
bw.write("\r\n");
bw.close();
}
}
This is a strange question, because it is incomplete and illogical.
Why is your question incomplete?
You are using MyImageRenderListener in the context of another example, ExtractImages:
PdfReader reader = new PdfReader(filename);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
MyImageRenderListener listener = new MyImageRenderListener(RESULT);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
parser.processContent(i, listener);
}
reader.close();
In this example, you loop over every page number to examine every separate page. Hence you know the page number whenever MyImageRenderListener returns an image.
Images are stored inside a PDF as external objects (aka XObject). MyImageRenderListener returns what's stored in such a stream object (containing the bytes of the image). So far, so good.
Why is your question illogical?
Because the whole purpose of storing images in XObject is to be able to reuse the same image stream. Imagine an image of a logo. That image can be present on every page of the document. In this case, MyImageRenderListener will give you the same image (from the same stream) as many times as there are pages, but in reality, there is only one image, and it's external to the page content. It doesn't make sense for that image to "know" the page it is on: it is on every page. The same logic applies even when the image is only used on one page. That is inherent to the design of PDF: an image stream doesn't know which page it belongs to. The link between the image stream and the page exists through the /XObject entry in the /Resources of the page dictionary.
What would be an elegant way to solve this?
Create a member-variable in MyImageRenderListener, e.g.:
protected int pagenumber;
public void setPagenumber(int pagenumber) {
this.pagenumber = pagenumber;
}
Use the setter from your loop:
PdfReader reader = new PdfReader(filename);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
MyImageRenderListener listener = new MyImageRenderListener(RESULT);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
listener.setPagenumber(i);
parser.processContent(i, listener);
}
reader.close();
Now you can use pagenumber in the renderImage(ImageRenderInfo renderInfo) method. This way, you'll always know which page is being examined when this method is triggered.
I want to add an image which is retrieved from the mysql db and print it on a pdf file in iText java. The image retrieved from the db is stored in the lblimg. How do I achieve that in java ?
Here's my partial code:
String filename = null;
int s = 0;
byte[] person_img = null;
uploadbtn = new JButton("Upload a Photo");
uploadbtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File f = chooser.getSelectedFile();
String filename = f.getAbsolutePath();
try{
File img = new File(filename);
FileInputStream fis = new FileInputStream(img);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for(int readNum; (readNum = fis.read(buf)) != -1;){
bos.write(buf, 0, readNum);
}
person_img = bos.toByteArray();
fis.close();
}catch(Exception e1){
e1.printStackTrace();
}
}
});
// Partial code for adding image to db
stt.setBytes(8, person_img);
// Partial codes for retrieving image from db
byte[] imageData = rs.getBytes("Image");
format = new ImageIcon(imageData);
lblimg.setIcon(format);
//Creating the document and adding the lblimg (which contains the image retrieved from the db). PLEASE HELP HERE. I CANNOT ADD THE IMAGE TO PDF document.
Document doc = new Document();
PdfWriter.getInstance(doc, new FileOutputStream("Report.pdf"));
doc.open();
doc.add(new Paragraph( // img to be added here ));
Update 1 by Bruno Lowagie
Snippet taken from the full code:
try {
Image i = Image.getInstance((PdfTemplate) lblimg.getIcon());
Document doc = new Document();
PdfWriter.getInstance(doc, new FileOutputStream("Report.pdf"));
doc.open();
Image img = Image.getInstance("ja.png");
doc.add(img);
doc.add(i);
doc.add(new Paragraph("Employee Information", FontFactory.getFont(FontFactory.TIMES_BOLD,18, Font.BOLD, BaseColor.RED)));
doc.add(new Paragraph("______________________________________________________________________________"));
doc.add(new Paragraph("Employee ID is " + val1));
doc.add(new Paragraph("First Name is " + val2 + "\t\t" + " Last Name is " + val3));
doc.add(new Paragraph("Job Position " + val4));
doc.add(new Paragraph("Allowances allowed " + val5));
doc.add(new Paragraph("Salary " + val10));
JOptionPane.showMessageDialog(null, "Report Saved");
doc.close();
} catch(Exception e1) {
e1.printStackTrace();
}
As getIcon returns a javax.swing class and as PdfTemplate is an iText class extending the PdfContentByte class that contains a ByteBuffer of PDF syntax, a ClassCastException is thrown here: (PdfTemplate) lblimg.getIcon()
Update 2 by Bruno Lowagie
The actual question was posted as a comment: How do I retrieve an image which is in a JLabel and add it on a PDF? This question is answered in update 3 of my answer.
Assuming that this contains an image:
byte[] imageData = rs.getBytes("Image");
In other words: assuming that imageData is a valid JPEG, JPEG2000, GIF, PNG, BMP, WMF, TIFF or JBIG2 image, then you can create a com.itextpdf.text.Image object like this:
Image img = Image.getInstance(imageData);
Once you have this img instance, you can add it to the document like this:
document.add(img);
I don't understand why you'd create an ImageIcon instance. Nor is it clear why you refer to a Paragraph object.
Update 1:
Now that I see your full code, I see a very strange line:
Image i = Image.getInstance((PdfTemplate) lblimg.getIcon());
You are casting a javax.swing object to an iText object. This can never work. You should get a ClassCastException at this point in your code.
I also see that you know how to add an image from a file:
Image img = Image.getInstance("ja.png");
doc.add(img);
When you don't have a path to a file, the fastest way you'll find alternative getInstance() methods, is by consulting the Javadoc API documentation: http://api.itextpdf.com/itext/com/itextpdf/text/Image.html#getInstance(byte[])
Update 2:
I have updated the question so that it contains the relevant code. As explained in my answer (that unfortunately wasn't accepted), the following line throws a ClassCastException:
Image i = Image.getInstance((PdfTemplate) lblimg.getIcon());
This exception is caught like this:
} catch(Exception e1) {
e1.printStackTrace();
}
Hence all the code starting with the following line is skipped:
Document doc = new Document();
As a result, no document is created. This is not an iText problem. This is a case of bad exception handling.
Update 3:
Finally, the real question is asked in a comment: In simple words: How to I retrieve an image which is in a JLabel and add it on a PDF?
Again it turns out that I have already answered that question. I referred to the Javadoc API documentation for the Image class. We find the following getInstance() method: http://api.itextpdf.com/itext/com/itextpdf/text/Image.html#getInstance(java.awt.Image, java.awt.Color)
In other words, we can create an iText Image object using a Java Image object. You have the following line in your code:
ImageIcon format = new ImageIcon(imageData);
Or, in your case, you could try something like:
ImageIcon format = (ImageIcon)lblimg.getIcon();
You can get a java.awt.Image object from this ImageIcon like this:
java.awt.Image awtImage = format.getImage();
As per the iText API documentation, you can create an iText image like this:
Image img = Image.getInstance(awtImage, null);
I was wondering if it was possible to mark strings in pdf with different color or underline them while looping through the pdf document ?
It's possible on creating a document. Just use different chunks to set the style. Here's an example:
Document document = new Document();
PdfWriter.getInstance(document, outputStream);
document.open();
document.add(new Chunk("This word is "));
Chunk underlined = new Chunk("underlined");
underlined.setUnderline(1.0f, -1.0f); //We can customize thickness and position of underline
document.add(underlined);
document.add(new Chunk(". And this phrase has "));
Chunk background = new Chunk("yellow background.");
background.setBackground(BaseColor.YELLOW);
document.add(background);
document.add(Chunk.NEWLINE);
document.close();
However, it's almost impossible to edit an existing PDF document. The author of iText writes in his book:
In a PDF document, every character or glyph on a PDF page has its
fixed position, regardless of the application that’s used to view the
document. This is an advantage, but it also comes with a disadvantage.
Suppose you want to replace the word “edit” with the word “manipulate”
in a sentence, you’d have to reflow the text. You’d have to reposition
all the characters that follow that word. Maybe you’d even have to
move a portion of the text to the next page. That’s not trivial, if
not impossible.
If you want to “edit” a PDF, it’s advised that you change the original
source of the document and remake the PDF.
Aspose.PDF APIs support to create new PDF document and manipulate existing PDF documents without Adobe Acrobat dependency. You can search and add Highlight Annotation to mark PDF text.
REST API Solution using Aspose.PDF Cloud SDK for Java:
// For complete examples and data files, please go to https://github.com/aspose-pdf-cloud/aspose-pdf-cloud-java
String name = "02_pages.pdf";
String folder="Temp";
String remotePath=folder+"/"+name;
// File to upload
File file = new File("C:/Temp/"+name);
// Storage name is default storage
String storage = null;
// Get App Key and App SID from https://dashboard.aspose.cloud/
PdfApi pdfApi = new PdfApi("xxxxxxxxxxxxxxxxxxxx", "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx");
//Upload file to cloud storage
pdfApi.uploadFile(remotePath,file,storage);
//Text Position
Rectangle rect = new Rectangle().LLX(259.27580539703365).LLY(743.4707997894287).URX(332.26148873138425).URY(765.5148007965088);
List<AnnotationFlags> flags = new ArrayList<>();
flags.add(AnnotationFlags.DEFAULT);
HighlightAnnotation annotation = new HighlightAnnotation();
annotation.setName("Name Updated");
annotation.rect(rect);
annotation.setFlags(flags);
annotation.setHorizontalAlignment(HorizontalAlignment.CENTER);
annotation.setRichText("Rich Text Updated");
annotation.setSubject("Subj Updated");
annotation.setPageIndex(1);
annotation.setZindex(1);
annotation.setTitle("Title Updated");
annotation.setModified("02/02/2018 00:00:00.000 AM");
List<HighlightAnnotation> annotations = new ArrayList<>();
annotations.add(annotation);
//Add Highlight Annotation to the PDF document
AsposeResponse response = pdfApi.postPageHighlightAnnotations(name,1, annotations, storage, folder);
//Download annotated PDF file from Cloud Storage
File downloadResponse = pdfApi.downloadFile(remotePath, null, null);
File dest = new File("C:/Temp/HighlightAnnotation.pdf");
Files.copy(downloadResponse.toPath(), dest.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
System.out.println("Completed......");
On-Premise Solution using Aspose.PDF for Java:
// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-Java
// Instantiate Document object
Document document = new Document("C:/Temp/Test.pdf");
// Create TextFragment Absorber instance to search particular text fragment
TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("Estoque");
// Iterate through pages of PDF document
for (int i = 1; i <= document.getPages().size(); i++) {
// Get first page of PDF document
Page page = document.getPages().get_Item(i);
page.accept(textFragmentAbsorber);
}
// Create a collection of Absorbed text
TextFragmentCollection textFragmentCollection = textFragmentAbsorber.getTextFragments();
// Iterate on above collection
for (int j = 1; j <= textFragmentCollection.size(); j++) {
TextFragment textFragment = textFragmentCollection.get_Item(j);
// Get rectangular dimensions of TextFragment object
Rectangle rect = new Rectangle((float) textFragment.getPosition().getXIndent(), (float) textFragment.getPosition().getYIndent(), (float) textFragment.getPosition().getXIndent() + (float) textFragment.getRectangle().getWidth(), (float) textFragment.getPosition().getYIndent() + (float) textFragment.getRectangle().getHeight());
// Instantiate HighLight Annotation instance
HighlightAnnotation highLight = new HighlightAnnotation(textFragment.getPage(), rect);
// Set opacity for annotation
highLight.setOpacity(.80);
// Set the color of annotation
highLight.setColor(Color.getYellow());
// Add annotation to annotations collection of TextFragment
textFragment.getPage().getAnnotations().add(highLight);
}
// Save updated document
document.save("C:/Temp/HighLight.pdf");
P.S: I work as support/evangelist developer at Aspose.
I'm reading some text from a .txt file and writing those to a pdf file.But in my pdf the texts are showing as some bigger fonts. Even though I've changed the font size of the .txt file to bigger or too small the fonts in pdf will be same.
Part of my code which is working with reading writing in text file
Document document = new Document(PageSize.A4.rotate(), 36, 36, 80, 160);
........
.........
document.newPage();
//Writing in a default page from the txt file
document.add(new com.lowagie.text.Paragraph("\n"));
iStream = new FileInputStream(path1); //path1 is location of .txt file
in = new DataInputStream(iStream);
is = new InputStreamReader(in);
br = new BufferedReader(is);
String strLine;
while ((strLine = br.readLine()) != null)
{
Paragraph para = new com.lowagie.text.Paragraph(strLine + "\n");
para.setAlignment(Element.ALIGN_JUSTIFIED);
document.add(new com.lowagie.text.Paragraph(strLine + "\n"));
}
br.close();
is.close();
in.close();
iStream.close();
document.close();
writer.close();
Sorry I'm using the lower version of itext because right now I can't add any third party library to my windchill.This version of itext already my windchill have in it.
How to set the font size inside pdf file when writing into it.?Any help would be really helpful.
Quite simple :D
Fist, i would change one thing:
while ((strLine = br.readLine()) != null) {
Paragraph para = new com.lowagie.text.Paragraph(strLine + "\n");
para.setAlignment(Element.ALIGN_JUSTIFIED);
document.add(para);
}
This way, the paragraph is justified in the document. The way you did it, you changed the text alignment of one paragaph-object, but then added a new, totally different one to the PDF.
Now to your problem:
You can specify the Font in each Paragraph` contructor as follows:
Paragraph para = new com.lowagie.text.Paragraph(strLine + "\n", FontFactory.getFont("Arial", 14f /*This is the size, but as a float!*/);
The entire documentation of the lowagie API can be found here.
Best Regards
When I open up my file in my text editor. I am only getting the file's location in the text pane. Am I making a simple mistake somewhere or is there a better way to do this? Should I use an ArrayList to store the images locations?
Example of what is happening: I have a file that has two lines...
C:\...\pic.png
(picture description)
When I try to open up the file (after I save it in the text editor) it shows the actual location of the picture. I want to be able to use BufferedImage to get the directory and add the image to the JTextPane. Otherwise (if the text isn't a location), simply add the text to the text pane.
FYI: textArea is of type JTextPane
Code that opens my file
// sb is my StringBuffer
try
{
b = new BufferedReader(new FileReader(filename));
String line;
while((line=b.readLine())!=null)
{
if (line.contains("C:\\...\\Pictures\\"))
{
BufferedImage image = ImageIO.read(new File(line));
ImageIcon selectedPicture = new ImageIcon(image);
textArea.insertIcon(selectedPicture);
}
sb.append(line + "\n");
textArea.setText(sb.toString());
}
b.close();
}
If you have any questions about this code or need clarification, don't hesitate to ask.
OK. The way you are setting content on to the JTextPane is incorrect.
The basic trick is to get StyleDocument out of the JTextPane and then set a Style on the document. A style basically explains how the component needs to be rendered. For example, text formatting, image icons, spacing etc.
Given that following code will get you started.
JTextPane textPane = new JTextPane();
try {
BufferedReader b = new BufferedReader(
new FileReader("inputfile.txt"));
String line;
StyledDocument doc = (StyledDocument) textPane.getDocument();
while ((line = b.readLine()) != null) {
if (line.contains("/home/user/pictures")) {
Style style = doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, new ImageIcon(line));
doc.insertString(doc.getLength(), "ignore", style);
} else {
Style textStyle = doc.addStyle("StyleName", null);
//work on textStyle object to get required color/formatting.
doc.insertString(doc.getLength(), "\n" + line, textStyle);
}
}
b.close();
} catch (Exception e) {
e.printStackTrace();
}