Appending text to existing word file using XWPFDocument - java

I am trying to append a text and screenshot to the existing word file. But every time I execute the below code I am getting error as :
org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long) at
org.apache.poi.util.IOUtils.peekFirstNBytes(IOUtils.java:74) at
org.apache.poi.util.IOUtils.peekFirst8Bytes(IOUtils.java:57) at
org.apache.poi.poifs.filesystem.FileMagic.valueOf(FileMagic.java:135)
at
org.apache.poi.openxml4j.opc.internal.ZipHelper.verifyZipHeader(ZipHelper.java:175)
at
org.apache.poi.openxml4j.opc.internal.ZipHelper.openZipStream(ZipHelper.java:209)
at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:98)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:324)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37) at
org.apache.poi.xwpf.usermodel.XWPFDocument.(XWPFDocument.java:116)
at test.tester.(tester.java:44) at
test.tester.main(tester.java:100)
failed to create file Taking first ss
java.lang.NullPointerException at test.tester.setText(tester.java:62)
at test.tester.main(tester.java:103)
Here is the code:
public class tester{
FileOutputStream fos = null;
XWPFDocument doc = null;
// create para and run
XWPFParagraph para = null;
XWPFRun run = null;
File file = null;
public tester() {
try {
file = new File("WordDocWithImage.docx");
writeToWord();
//doc = new XWPFDocument();
doc = new XWPFDocument(OPCPackage.open(file));
//doc = new XWPFDocument(new FileInputStream("WordDocWithImage.docx"));
para = doc.createParagraph();
run = para.createRun();
para.setAlignment(ParagraphAlignment.CENTER);
} catch (Exception e) {
e.printStackTrace();
System.out.println("failed to create file");
}
}
public FileOutputStream writeToWord() throws FileNotFoundException {
fos = new FileOutputStream("WordDocWithImage.docx");
return fos;
}
public void setText(String text) {
run.setText(text);
}
public void takeScreenshot() throws IOException, AWTException, InvalidFormatException {
// Take screenshot
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
// convert buffered image to Input Stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(screenFullImage, "jpeg", baos);
baos.flush();
ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
baos.close();
// add image to word doc
run.addBreak();
run.addPicture(bis, XWPFDocument.PICTURE_TYPE_JPEG, "image file", Units.toEMU(450), Units.toEMU(250)); // 200x200
// pixels
bis.close();
}
public void writeToFile() {
try {
// write word doc to file
doc.write(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
tester t = new tester();
try {
System.out.println("Taking first ss");
t.setText("First Text");
t.takeScreenshot();
System.out.println("Taking second ss");
t.setText("Second Text");
t.takeScreenshot();
t.writeToFile();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Please assist.

The supplied file was empty (zero bytes long)
The problem is about getting the WordDocWithImage file in this line.
file = new File("WordDocWithImage.docx");
It could not find the docx file. You should check the location of the file and give the true path in there.
EDIT: You need to change the outputStream to different location. You can create a subfolder. I got ss trying this.
public FileOutputStream writeToWord() throws FileNotFoundException {
fos = new FileOutputStream("path/subFolder/WordDocWithImage.docx");
return fos;
}
Note: I have tried the code.

Related

JavaFX application: printer cannot print file

I am creating a PDF document in tDEST by itext library. Then I am cleaning trailing spaces in resize functions writing a new document to DEST. If I want to print tDest document, it works fine but if I try to print a DEST file, it does not print anything and does not throw any exception.
Here is my main class:
String DEST = System.getProperty("user.home") + "\\Documents\\invoice.pdf";
String tDEST = System.getProperty("user.home") + "\\Documents\\temp.pdf";
public static void main(String... args) {
....
resize();
PDDocument document = null;
try {
document = PDDocument.load(new File(DEST));
} catch (IOException e) {
e.printStackTrace();
}
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document));
try {
PrintService myPrintService = findPrintService(Commons.printer.getName());
job.setPrintService(myPrintService);
job.print();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Printer ishlamayapti");
}
....
}
public void resize() {
try {
FileOutputStream fileOutputStream = new FileOutputStream(DEST);
PdfReader reader = new PdfReader(tDEST);
com.itextpdf.text.Rectangle pageSize = reader.getPageSize(1);
PdfStamper stamper = new PdfStamper(reader, fileOutputStream);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
TextMarginFinder finder = parser.processContent(1, new TextMarginFinder());
PdfDictionary page = reader.getPageN(1);
page.put(PdfName.CROPBOX, new PdfArray(new float[]{pageSize.getLeft(), finder.getLly(), pageSize.getRight(), pageSize.getTop()}));
stamper.markUsed(page);
stamper.flush();
stamper.close();
reader.close();
fileOutputStream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}

Can't read Arabic PDF file with custom font

I have an Arabic PDF file which contains a custom font, so when I try to read the file I faced some unreadable words and characters replaced with another character or symbol.
Here is the link to the PDF file I'm working on.
public class TikaAnalysis {
public static String extractContentUsingFacade(InputStream stream) throws IOException, TikaException {
Tika tika = new Tika();
String content = tika.parseToString(stream);
try {
WriteOnWordDoc(str);
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
public static void WriteOnWordDoc(String fileContent) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph tmpParagraph = document.createParagraph();
XWPFRun tmpRun = tmpParagraph.createRun();
tmpRun.setText(fileContent);
tmpRun.setFontSize(10);
FileOutputStream fos = new FileOutputStream(new File("extractedContent.docx"));
document.write(fos);
fos.close();
}
public static void main(String[] args) {
FileInputStream inputStream = null;
String path ="File.pdf";
try {
File file=new File(path);
inputStream = new FileInputStream(file);
InputStream input = new BufferedInputStream(inputStream);
TikaAnalysis.extractContentUsingFacade(inputStream);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
System.out.println("close the file ");
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

How can i edit pdf and put it inside zip during stream then download using IText and java?

My use case is this: when the client clicks download on a pdf, I want to edit/write some text on to the pdf using Itext pdf editor, then zip the pdf then let it download, All during the stream. I am aware of memory issue if the pdf is large etc. which won't be an issue since its like 20-50kb. I have the zipping during the stream before downloading working using byte array, now have to make the pdfeditor method also run before zipping, add some text then let the download happen.
Here is my code so far:
public class zipfolder {
public static void main(String[] args) {
try {
System.out.println("opening connection");
URL url = new URL("http://gitlab.itextsupport.com/itext/sandbox/raw/master/resources/pdfs/form.pdf");
InputStream in = url.openStream();
// FileOutputStream fos = new FileOutputStream(new
// File("enwiki.png"));
PdfEditor writepdf = new PdfEditor();
writepdf.manipulatePdf(url, dest, "field"); /// where i belive i
/// should execute the
/// editor function ?
File f = new File("test.zip");
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(f));
ZipEntry entry = new ZipEntry("newform.pdf");
zos.putNextEntry(entry);
System.out.println("reading from resource and writing to file...");
int length = -1;
byte[] buffer = new byte[1024];// buffer for portion of data from
// connection
while ((length = in.read(buffer)) > -1) {
zos.write(buffer, 0, length);
}
zos.close();
in.close();
System.out.println("File downloaded");
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
}
public class PdfEditor {
public String insertFields (String field, String value) {
return field + " " + value;
// System.out.println("does this work :" + field);
}
// public static final String SRC = "src/resources/source.pdf";
// public static final String DEST = "src/resources/Destination.pdf";
//
// public static void main(String[] args) throws DocumentException,
// IOException {
// File file = new File(DEST);
// file.getParentFile().mkdirs();
// }
public String manipulatePdf(URL src, String dest, String field) throws Exception {
System.out.println("test");
try {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
Item item = form.getFieldItem("Name");
PdfDictionary widget = item.getWidget(0);
PdfArray rect = widget.getAsArray(PdfName.RECT);
rect.set(2, new PdfNumber(rect.getAsNumber(2).floatValue() + 20f));
String value = field;
form.setField("Name", value);
form.setField("Company", value);
stamper.close();
} catch (Exception e) {
System.out.println("Error in manipulate");
System.out.println(e.getMessage());
throw e;
}
return field;
}
}
So playing with ByteArrayOutputStream, finally got it work. passing the input stream to 'manipulatepdf' and returning 'bytedata'.
public ByteArrayOutputStream manipulatePdf(InputStream in, String field) throws Exception {
System.out.println("pdfediter got hit");
ByteArrayOutputStream bytedata = new ByteArrayOutputStream();
try {
PdfReader reader = new PdfReader(in);
PdfStamper stamper = new PdfStamper(reader, bytedata);
AcroFields form = stamper.getAcroFields();
Item item = form.getFieldItem("Name");
PdfDictionary widget = item.getWidget(0);
PdfArray rect = widget.getAsArray(PdfName.RECT);
rect.set(2, new PdfNumber(rect.getAsNumber(2).floatValue() + 20f));
String value = field;
form.setField("Name", value);
form.setField("Company", value);
stamper.close();
} catch (Exception e) {
System.out.println("Error in manipulate");
System.out.println(e.getMessage());
throw e;
}
return bytedata;
}
public String editandzip (String data, String Link) {
try {
System.out.println("opening connection");
URL url = new URL(Link);
InputStream in = url.openStream();
System.out.println("in : "+ url);
//String data = "working ok with main";
PdfEditor writetopdf = new PdfEditor();
ByteArrayOutputStream bao = writetopdf.manipulatePdf(in, data);
byte[] ba = bao.toByteArray();
File f = new File("C:/Users/JayAcer/workspace/test/test.zip");
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(f));
ZipEntry entry = new ZipEntry("newform.pdf");
entry.setSize(ba.length);
zos.putNextEntry(entry);
zos.write(ba);
zos.close();
in.close();
System.out.println("File downloaded");
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
return data;
}
}

Java PDF format error

I have to create an new class to create an new pdf file in java.
This is my code.
public class Createpdf {
public static void main(String[] args) {
try {
InputStream file = new FileInputStream(new File("E:\\dev\\training\\practice\\java\\30-09-2015\\Invoice.pdf"));
PdfReader reader = new PdfReader(file);
PdfCopyFields copy = new PdfCopyFields(new FileOutputStream("concatenatedforms.pdf"));
copy.addDocument(reader);
file.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
But while opening the file it displays but shows error "There is a problem with file format" I am a beginner may I know the exact problem
To solve the error use this code below.
public static void main(String[] args) {
try {
InputStream file = new FileInputStream(new File("C:\\temp\\528.pdf"));
FileOutputStream copy = new FileOutputStream("C:\\temp\\concatenatedforms.pdf");
int b;
while ((b = file.read()) != -1) {
copy.write(b);
}
file.close();
} catch(Exception e) {
System.out.println(e);
}
}

How to add background image to pdf Document using Itext? [duplicate]

I am creating a PDF and writing the stream in response. Before writing in the stream, I want to add a background image as watermark in all the pages so that PDF document flushed through response is the final one with watermark.
Hi this is my code sample. Any help would be much appriciated
private static String generatePDF(HttpServletRequest request, HttpServletResponse response, String fileName) throws Exception
{
Document document = null;
PdfWriter writer = null;
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(fileName);
Document document = new Document(PageSize.A4);
writer = PdfWriter.getInstance(document, fos);
document.open();
/**
* Adding tables and cells and other stuff required
**/
return pdfFileName;
} catch (Exception e) {
FileUtil.deleteFile(fileName);
throw e
} finally {
if (document != null) {
document.close();
}
fos.flush();
}
}
I now would like to add a background image using the below code and write the output PDF to the same stream
PdfReader sourcePDFReader = null;
try
{
sourcePDFReader = new PdfReader(sourcePdfFileName);
int noOfPages = sourcePDFReader.getNumberOfPages();
PdfStamper stamp = new PdfStamper(sourcePDFReader, new FileOutputStream(destPdfFileName));
int i = 0;
Image templateImage = Image.getInstance(templateImageFile);
templateImage.setAbsolutePosition(0, 0);
PdfContentByte tempalteBytes;
while (i < noOfPages) {
i++;
tempalteBytes = stamp.getUnderContent(i);
tempalteBytes.addImage(templateImage);
}
stamp.close();
return destPdfFileName;
} catch (Exception ex) {
LOGGER.log(Level.INFO, "Error when applying tempalte image as watermark");
} finally {
if (sourcePDFReader != null) {
sourcePDFReader.close();
}
}
I solved this using Bruno's first (recommended) approach.
1) Create a page event helper with an onEndPage event:
class PDFBackground extends PdfPageEventHelper {
#Override
void onEndPage(PdfWriter writer, Document document) {
Image background = Image.getInstance("myimage.png");
// This scales the image to the page,
// use the image's width & height if you don't want to scale.
float width = document.getPageSize().getWidth();
float height = document.getPageSize().getHeight();
writer.getDirectContentUnder()
.addImage(background, width, 0, 0, height, 0, 0);
}
}
2) When creating your writer, register your page event helper:
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setPageEvent(new PDFBackground());
I have solved this with Bruno's second option. Here is the code.
public static String addBackgroundImageToPDF(ByteArrayOutputStream bos, String destPdfFileName, String templateImageFile)
{
PdfReader sourcePDFReader = null;
try
{
sourcePDFReader = new PdfReader(bos.toByteArray());
int noOfPages = sourcePDFReader.getNumberOfPages();
PdfStamper stamp = new PdfStamper(sourcePDFReader, new FileOutputStream(destPdfFileName));
int i = 0;
Image templateImage = Image.getInstance(templateImageFile);
templateImage.setAbsolutePosition(0, 0);
PdfContentByte tempalteBytes;
while (i < noOfPages)
{
i++;
tempalteBytes = stamp.getUnderContent(i);
tempalteBytes.addImage(templateImage);
}
stamp.close();
return destPdfFileName;
}
catch (Exception ex)
{
LOGGER.log(Level.INFO, "Error when applying template image as watermark");
}
finally
{
if (sourcePDFReader != null)
{
sourcePDFReader.close();
}
}
}
You can choose between two options:
Use the background image in a page event (to the 'under' content in the onEndPage() method)/
Create the first PDF in memory, then add the background image in a second pass using the code you posted.
I prefer option 1.

Categories