adding image to word document using docx4j - java

I am trying to add an image to the word document I want to create from docx4j..
Here goes my code..
package presaleshelperapplication;
import java.io.ByteArrayOutputStream;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import sun.misc.IOUtils;
public class PreSalesHelperApplication {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws Exception {
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
//wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Title", "Hello World");
//wordMLPackage.getMainDocumentPart().addParagraphOfText("Text");
java.io.InputStream is = new java.io.FileInputStream("/D:/Development/PreSalesData/sample.jpg");
// commons-io.jar
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = baos.toByteArray();
String filenameHint = null;
String altText = null;
int id1 = 0;
int id2 = 1;
org.docx4j.wml.P p = newImage( wordMLPackage, bytes,filenameHint, altText,id1, id2,6000 );
// Now add our p to the document
wordMLPackage.getMainDocumentPart().addObject(p);
wordMLPackage.save(new java.io.File("helloworld.docx") );
is.close();
}
public static org.docx4j.wml.P newImage( WordprocessingMLPackage wordMLPackage,
byte[] bytes,
String filenameHint, String altText,
int id1, int id2, long cx) throws Exception {
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
Inline inline = imagePart.createImageInline(filenameHint, altText,id1, id2, cx,false);
// Now add the inline in w:p/w:r/w:drawing
org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
org.docx4j.wml.P p = factory.createP();
org.docx4j.wml.R run = factory.createR();
p.getContent().add(run);
org.docx4j.wml.Drawing drawing = factory.createDrawing();
run.getContent().add(drawing);
drawing.getAnchorOrInline().add(inline);
return p;
}
}
When compiling I am getting the following error...
Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/xmlgraphics/image/loader/ImageContext
My image file is good but getting this error..what could be the prob?

docx4j has dependencies.
One of them is:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
<version>1.5</version>
</dependency>
You need to add this to your class path.

Related

Word found unreadable content in .docx after replacing content through docx4j

I am getting error Word found unreadable content in .docx after replacing content through docx4j.
Please find code snippet.
I am using docx4j-6.1.2 jar
public class Testt {
public static void main(String[] args) throws Exception {
final String TEMPLATE_NAME = "D://fileuploadtemp//123.docx";
InputStream templateInputStream = new FileInputStream(TEMPLATE_NAME);
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(templateInputStream);
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
String xpath = "//w:r[w:t[contains(text(),'TEST')]]";
List<Object> list = documentPart.getJAXBNodesViaXPath(xpath, true);
for (Object obj : list) {
org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
org.docx4j.wml.Text t = factory.createText();
t.setValue("\r\n");
((R) obj).getContent().clear();
((R) obj).getContent().add(t);
}
OutputStream os = new FileOutputStream(new File("D://fileuploadtemp//1234.docx"));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
wordMLPackage.save(outputStream);
outputStream.writeTo(os);
os.close();
outputStream.close();
templateInputStream.close();
}
}

Java - Merge multiple images to a single PDF using PDFBox

I was able to merge multiple PDF files into a single PDF using the code below -
public void mergePDF() {
File file1 = new File("inputPDF/001.pdf");
File file2 = new File("inputPDF/002.pdf");
File file3 = new File("inputPDF/003.pdf");
File file4 = new File("inputPDF/004.pdf");
try {
PDDocument doc1 = PDDocument.load(file1);
PDDocument doc2 = PDDocument.load(file2);
PDDocument doc3 = PDDocument.load(file3);
PDDocument doc4 = PDDocument.load(file4);
PDFMergerUtility PDFmerger = new PDFMergerUtility();
PDFmerger.setDestinationFileName("outputImages/merged.pdf");
System.out.println("Destination path set to "+PDFmerger.getDestinationFileName());
PDFmerger.addSource(file1);
PDFmerger.addSource(file2);
PDFmerger.addSource(file3);
PDFmerger.addSource(file4);
//Merging the documents
PDFmerger.mergeDocuments();
doc1.close();
doc2.close();
doc3.close();
doc4.close();
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
}
}
However, my requirement is to merge multiple images (JPG, PNG) to a single PDF as well.
Is it possible to merge multiple images to a single PDF using PDFBox?
Since I struggled with this task, here's my code. The merged document is PDF/A-1b compliant
import com.google.common.io.Resources;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Calendar;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.preflight.parser.PreflightParser;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.DublinCoreSchema;
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
import org.apache.xmpbox.schema.XMPBasicSchema;
import org.apache.xmpbox.type.BadFieldValueException;
import org.apache.xmpbox.xml.XmpSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class PDFMerger {
private static final Logger LOG = LoggerFactory.getLogger(PDFMerger3.class);
private static final String OUTPUT_CONDITION_IDENTIFIER = "sRGB IEC61966-2.1";
public static final String DOCUMENT_CREATOR = "Mr. Meeseeks";
public static final String DOCUMENT_SUBJECT = "Great subject";
public static final String DOCUMENT_TITLE = "Here goes your title";
/**
* Creates a compound PDF document from a list of input documents.
* <p>
* The merged document is PDF/A-1b compliant
*
* #param sources list of source PDF document streams.
* #return compound PDF document as a readable input stream.
* #throws IOException if anything goes wrong during PDF merge.
*/
public static ByteArrayOutputStream mergeFiles(final List<InputStream> sources) throws IOException {
Path mergeDirectory = Files.createTempDirectory("merge-" + System.currentTimeMillis());
try (ByteArrayOutputStream mergedPDFOutputStream = new ByteArrayOutputStream()) {
LOG.debug("Merging {} source documents into one PDF", sources.size());
PDFMergerUtility mixedPdfMerger = createMixedPdfMerger(sources, mergedPDFOutputStream, mergeDirectory);
mergeFileStreams(mergedPDFOutputStream, mixedPdfMerger);
return mergedPDFOutputStream;
} catch (Exception e) {
if (!(e instanceof IOException)) {
throw new IOException("PDF merge problem", e);
}
throw (IOException) e;
} finally {
FileUtils.deleteDirectory(mergeDirectory.toFile());
sources.forEach(IOUtils::closeQuietly);
}
}
private static void mergeFileStreams(ByteArrayOutputStream mergedPDFOutputStream, PDFMergerUtility pdfMerger)
throws IOException, BadFieldValueException, TransformerException {
LOG.debug("Initialising PDF merge utility");
try (COSStream cosStream = new COSStream()) {
// PDF and XMP properties must be identical, otherwise document is not PDF/A compliant
pdfMerger.setDestinationDocumentInformation(createPDFDocumentInfo());
pdfMerger.setDestinationMetadata(createXMPMetadata(cosStream));
pdfMerger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
LOG.debug("PDF merge successful, size = {} bytes", mergedPDFOutputStream.size());
}
}
#SuppressWarnings("UnstableApiUsage")
private static PDFMergerUtility createMixedPdfMerger(List<InputStream> sources, ByteArrayOutputStream mergedPDFOutputStream, Path mergeDirectory) throws IOException {
PDFMergerUtility pdfMerger = new PDFMergerUtility();
byte[] colorProfile = org.apache.commons.io.IOUtils.toByteArray(Resources.getResource("sRGB.icc"));
for (InputStream source : sources) {
File file = streamToFile(mergeDirectory, source);
if (isPdf(file)) {
pdfMerger.addSource(file);
} else {
pdfMerger.addSource(imageToPDDocument(mergeDirectory, file, colorProfile));
}
}
pdfMerger.setDestinationStream(mergedPDFOutputStream);
return pdfMerger;
}
private static PDDocumentInformation createPDFDocumentInfo() {
LOG.debug("Setting document info (title, author, subject) for merged PDF");
PDDocumentInformation documentInformation = new PDDocumentInformation();
documentInformation.setTitle(DOCUMENT_TITLE);
documentInformation.setCreator(DOCUMENT_CREATOR);
documentInformation.setSubject(DOCUMENT_SUBJECT);
return documentInformation;
}
private static PDMetadata createXMPMetadata(COSStream cosStream)
throws BadFieldValueException, TransformerException, IOException {
LOG.debug("Setting XMP metadata (title, author, subject) for merged PDF");
XMPMetadata xmpMetadata = XMPMetadata.createXMPMetadata();
// PDF/A-1b properties
PDFAIdentificationSchema pdfaSchema = xmpMetadata.createAndAddPFAIdentificationSchema();
pdfaSchema.setPart(1);
pdfaSchema.setConformance("B");
pdfaSchema.setAboutAsSimple("");
// Dublin Core properties
DublinCoreSchema dublinCoreSchema = xmpMetadata.createAndAddDublinCoreSchema();
dublinCoreSchema.setTitle(DOCUMENT_TITLE);
dublinCoreSchema.addCreator(DOCUMENT_CREATOR);
dublinCoreSchema.setDescription(DOCUMENT_SUBJECT);
// XMP Basic properties
XMPBasicSchema basicSchema = xmpMetadata.createAndAddXMPBasicSchema();
Calendar creationDate = Calendar.getInstance();
basicSchema.setCreateDate(creationDate);
basicSchema.setModifyDate(creationDate);
basicSchema.setMetadataDate(creationDate);
basicSchema.setCreatorTool(DOCUMENT_CREATOR);
// Create and return XMP data structure in XML format
try (ByteArrayOutputStream xmpOutputStream = new ByteArrayOutputStream();
OutputStream cosXMPStream = cosStream.createOutputStream()) {
new XmpSerializer().serialize(xmpMetadata, xmpOutputStream, true);
cosXMPStream.write(xmpOutputStream.toByteArray());
return new PDMetadata(cosStream);
}
}
private static File imageToPDDocument(Path mergeDirectory, File file, byte[] colorProfile) throws IOException {
try (PDDocument doc = new PDDocument()) {
PDImageXObject pdImage = PDImageXObject.createFromFileByContent(file, doc);
drawPage(doc, pdImage);
doc.getDocumentCatalog().addOutputIntent(createColorScheme(doc, colorProfile));
File pdfFile = Files.createTempFile(mergeDirectory, String.valueOf(System.currentTimeMillis()), ".tmp").toFile();
doc.save(pdfFile);
return pdfFile;
}
}
private static void drawPage(PDDocument doc, PDImageXObject pdImage) throws IOException {
PDPage page;
pdImage.getCOSObject().setItem(COSName.SMASK, COSName.NONE);
boolean isLandscapeMode = pdImage.getWidth() > pdImage.getHeight();
if (isLandscapeMode) {
page = new PDPage(new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth()));
float scale = Math.min(Math.min(PDRectangle.A4.getWidth() / pdImage.getHeight(), PDRectangle.A4.getHeight() / pdImage.getWidth()), 1);
float width = pdImage.getWidth() * scale;
float height = pdImage.getHeight() * scale;
// center the image
float startWidth = (PDRectangle.A4.getHeight() - width) / 2;
float startHeight = (PDRectangle.A4.getWidth() - height) / 2;
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
contentStream.drawImage(pdImage, startWidth, startHeight, width, height);
}
} else {
page = new PDPage(PDRectangle.A4);
float scale = Math.min(Math.min(PDRectangle.A4.getWidth() / pdImage.getWidth(), PDRectangle.A4.getHeight() / pdImage.getHeight()), 1);
float width = pdImage.getWidth() * scale;
float height = pdImage.getHeight() * scale;
// try to center the image
float startWidth = (PDRectangle.A4.getWidth() - width) / 2;
float startHeight = (PDRectangle.A4.getHeight() - height) / 2;
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
contentStream.drawImage(pdImage, startWidth, startHeight, width, height);
}
}
doc.addPage(page);
}
private static PDOutputIntent createColorScheme(PDDocument doc, byte[] colorProfile) throws IOException {
PDOutputIntent intent = new PDOutputIntent(doc, new ByteArrayInputStream(colorProfile));
intent.setInfo(OUTPUT_CONDITION_IDENTIFIER);
intent.setOutputCondition(OUTPUT_CONDITION_IDENTIFIER);
intent.setOutputConditionIdentifier(OUTPUT_CONDITION_IDENTIFIER);
intent.setRegistryName("http://www.color.org");
return intent;
}
private static boolean isPdf(File file) {
try {
PreflightParser preflightParser = new PreflightParser(file);
preflightParser.parse();
return true;
} catch (Exception e) {
return false;
}
}
private static File streamToFile(Path tempDirectory, InputStream in) throws IOException {
final Path tempFile = Files.createTempFile(tempDirectory, String.valueOf(System.currentTimeMillis()), ".tmp");
try (FileOutputStream out = new FileOutputStream(tempFile.toFile())) {
IOUtils.copy(in, out);
}
return tempFile.toFile();
}
}
You can take a look at this gist for an option to merge pdf files as well.
You need to convert the images to a PDF first. See How can I convert a PNG file to PDF using java? or Create PDF from a PNG image Or Java Panel for an example on how to do this.
After that, use pdfbox to merge the resulting pdfs.
I have used itext library for merging images and convert them to pdf
Here is the code
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(image_path+"\\"+image_name+".pdf"));
document.open();
Paragraph p = new Paragraph();
File files[] = new File(path).listFiles();
PdfPTable table = new PdfPTable(1);
for (File file : files) {
table.setWidthPercentage(100);
table.addCell(createImageCell(file.getAbsolutePath()));
}
document.add(table);
document.close();
Hope It helps

java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64

Admin please don't mark it as duplicate read my question completely. I am encrypting and decrypting some text but while running in same file with main its running fine but when i call its encrypt and decrypt function from outside. Its giving an error at runtime. I am attaching the code.
package desede;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import security.SHA256Algo;
import shradhafinalwiddesign.UpdateFile;
import shradhafinalwiddesign.UserRegistration;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Simple TripleDES Encrypt/Decrypt Test
* sha1, utf-8, no padding
*
* uses commons-codec-1.6
* javac -cp :commons-codec-1.6.jar TripleDESTest.java
* java -cp :commons-codec-1.6.jar TripleDESTest
*/
public class TripleDesDemo {
public static void main(String[] args) throws Exception {
String text = "textToEncrypt";
UserRegistration user = new UserRegistration() ;
user.setlUsername("tarunv") ;
user.setAnswer("tommysdsfdsfsd") ;
user.setLastaccess("pets namesdfsfds") ;
user.setLpassword("computersdfdsfd") ;
String h1 = SHA256Algo.createHash(user.getlUsername()) ;
String h2 = SHA256Algo.createHash(user.getLpassword()) ;
String h3 = SHA256Algo.createHash(user.getAnswer()) ;
String hash1 = UpdateFile.modifyHashValue(h1).substring(0, 24) ;
String hash2 = UpdateFile.modifyHashValue(h2) ;
String hash3 = UpdateFile.modifyHashValue(h3) ;
System.out.println(" key1 : "+hash1.length()+" key2 : "+hash2.length()+" key3 : "+hash3.length());
byte[] arr = toByteArray(user) ;
byte[] codedtext = TripleDesDemo._encrypt(arr,"tarunvermacdac#gmail.com");
byte[] codedtext1 = TripleDesDemo._encrypt(codedtext,"tarun.spicyabc#gmail.com");
byte[] codedtext2 = TripleDesDemo._encrypt(codedtext1,"direct_tarun#yahoo.co.in");
writeSmallBinaryFile(codedtext2, "tarun.bat") ;
byte[] texttoDecrypt = readSmallBinaryFile("tarun.bat");
byte[] decodedtext = TripleDesDemo._decrypt(texttoDecrypt,"direct_tarun#yahoo.co.in");
byte[] decodedtext1 = TripleDesDemo._decrypt(decodedtext,"tarun.spicyabc#gmail.com");
byte[] decodedtext2 = TripleDesDemo._decrypt(decodedtext1,"tarunvermacdac#gmail.com");
System.out.println(codedtext + " ---> " + toObject(decodedtext2));
}
public static byte[] _encrypt(byte[] plainTextBytes, String secretKey) throws Exception {
byte[] keyBytes = secretKey.getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
//byte[] plainTextBytes = message.getBytes("utf-8");
byte[] buf = cipher.doFinal(plainTextBytes);
byte [] base64Bytes = Base64.encodeBase64(buf);
//String base64EncryptedString = new String(base64Bytes);
return base64Bytes ;
}
public static byte[] _decrypt(byte[] encryptedText, String secretKey) throws Exception {
//byte[] message = Base64.decodeBase64(encryptedText);
byte[] message = Base64.decodeBase64(encryptedText);
byte[] keyBytes = secretKey.getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher decipher = Cipher.getInstance("DESede");
decipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = decipher.doFinal(message);
return plainText ;
//return toObject(plainText);
}
public static byte[] toByteArray(UserRegistration obj) throws IOException {
byte[] bytes = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
} finally {
if (oos != null) {
oos.close();
}
if (bos != null) {
bos.close();
}
}
return bytes;
}
public static UserRegistration toObject(byte[] bytes) throws IOException, ClassNotFoundException {
UserRegistration obj = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bis = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bis);
obj = (UserRegistration) ois.readObject();
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
return obj;
}
public static byte[] readSmallBinaryFile(String aFileName) throws IOException {
Path path = Paths.get(aFileName);
return Files.readAllBytes(path);
}
public static void writeSmallBinaryFile(byte[] aBytes, String aFileName) throws IOException {
Path path = Paths.get(aFileName);
Files.write(path, aBytes); //creates, overwrites
}
}
The code is running fine with main but not when i call its function from other class which is in other package. Here is the exception.
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64 at desede.TripleDesAlgo._encrypt(TripleDesAlgo.java:81)
And this is .classpath file
Thanks in advance for any help.
You are missing commons-codec.jar. Download it from http://commons.apache.org/proper/commons-codec/download_codec.cgi.
Then add it project build path. To do that right click the project, click Properties, click "Java Build Path", open "Library" tab, and click "Add External JARs...".
Or if you are using maven add dependency for
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>

How can I create a Global FileInputStream object, which will be available to access from other class within in my project?

What I wanted to do is create a global FileInputStream object and use it a long of my application.
I have the follow class which create my FileInputStream objec and return the result of my query over the XML file:
package Engine;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import com.ximpleware.AutoPilot;
import com.ximpleware.VTDException;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;
public class BACENGQueryXMLbyVTD {
public String query;
public String path;
public BACENGQueryXMLbyVTD(String query, String path) {
this.query = query;
this.path = path;
}
public ArrayList query() throws IOException, VTDException {
System.out.println(path);
File f = new File(path);
//System.out.println(f);
FileInputStream fis = new FileInputStream(f);
//System.out.println(fis);
byte[] xmlContent = new byte[(int) f.length()];
fis.read(xmlContent);
VTDGen vg = new VTDGen();
vg.setDoc(xmlContent);
vg.parse(false);
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
int node = 0;
ap.selectXPath(query);
int i;
ArrayList<String> interfaces = new ArrayList<String>();
while ((i = ap.evalXPath()) != -1) {
vn.push();
interfaces.add(vn.toString(i + 1));
}
ap.resetXPath();
return interfaces;
}
}
This class is called from my main class which has a loop.
for (int c = 0; c < nodeNames.size(); c++) {
String Queries2 = "/import_data/group/node[#name='" +nodeNames.get(c) + "']/interface/#network_value";
BACENGQueryXMLbyVTD getNodesInterfaces = new BACENGQueryXMLbyVTD(Queries2, TransitPath);
listOfNodeInterfaces = getNodesInterfaces.query();
}
It's working fine, however in order to reduce the consume of IO resource over my server HD. I would like to create an unique FileInputStream object and use it for each query whcih has to be executed.
Could somebody point out the way to do it?
Separate your concerns - BACENGQueryXMLbyVTD is both loading the data and executing the query.
First load the file into a byte[] outside your loop, then pass it to BACENGQueryXMLbyVTD. You might also want to pass the query as an argument to the query method.
You'll end up with a BACENGQueryXMLbyVTD that looks like this (with the disclaimer that I'm not familiar with VTD-XML, so this might the creation of objects from that API might not work exactly like this):
public class BACENGQueryXMLbyVTD
{
private byte[] doc;
public BACENGQueryXMLbyVTD(byte[] doc)
{
this.doc = doc;
}
public List<String> query(String query) throws IOException, VTDException
{
VTDGen generator = new VTDGen();
generator.setDoc(doc);
generator.parse(false);
VTDNav navigator = generator.getNav();
AutoPilot autoPilot = new AutoPilot(navigator);
autoPilot.selectXPath(query);
List<String> nodeInterfaces = new ArrayList<String>();
int i;
while ((i = autoPilot.evalXPath()) != -1)
{
navigator.push();
nodeInterfaces.add(navigator.toString(i + 1));
}
return nodeInterfaces;
}
}
That you can then call like:
byte[] xmlContent = ... //load the xml from anywhere you like, not just a file as previously.
BACENGQueryXMLbyVTD getNodesInterfaces = new BACENGQueryXMLbyVTD(xmlContent);
for (String nodeName : nodeNames)
{
String query = "/import_data/group/node[#name='" + nodeName + "']/interface/#network_value";
nodeInterfaces = getNodesInterfaces.query(query);
...
}
You might also want to switch to the standard Java XPATH APIs - they're a lot clearer and better documented than VTD-XML.

How to replace an image in PPT presentation with Apache POI

I'd like to know, if there any way to replace images in ppt presentaions via Apache POI?
I have a template, where I've placed the elements (text fields and images) and I found out how to replace text, but didn't find anything for images.
Replacing images can be done in two ways:
Simply replace the image inside pptx-file, which is a zip file, under the path (/ppt/media). Checkout this post howto do it ..
or the POI method is to remove the file and add a new one ... and maybe change few other image properties (width, height, ...) - see below for an example
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSheet;
import org.apache.xmlbeans.XmlCursor;
public class ReplaceImageInPptx {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("test2.pptx");
XMLSlideShow pptx = new XMLSlideShow(fis);
fis.close();
String blipNS[] = {
"http://schemas.openxmlformats.org/drawingml/2006/main",
"http://schemas.openxmlformats.org/presentationml/2006/main"
};
for (XSLFSheet slide : pptx.getSlides()) {
PackagePart packPart = slide.getPackagePart();
for (String ns : blipNS) {
XmlCursor picCur = slide.getXmlObject().newCursor();
picCur.selectPath("declare namespace p='"+ns+"' .//p:blip"); // or blipFill
while (picCur.toNextSelection()) {
// ... doesn't work for all namespaces ...
// CTBlipFillProperties blipFill = (CTBlipFillProperties)picCur.getObject();
// CTBlip blip = blipFill.getBlip();
// String relId = blip.getEmbed();
QName relName = new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "embed");
String relId = picCur.getAttributeText(relName);
// remove old media file and reference
PackageRelationship packRel = packPart.getRelationship(relId);
PackagePartName oldPartName = PackagingURIHelper.createPartName(packRel.getTargetURI());
packPart.getPackage().removePart(oldPartName);
// add something new
PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/smiley.jpg");
PackagePart part = pptx.getPackage().createPart(partName, "image/jpeg");
OutputStream partOs = part.getOutputStream();
FileInputStream fis2 = new FileInputStream("src/test/resources/smiley.jpg");
byte buf[] = new byte[1024];
for (int readBytes; (readBytes = fis2.read(buf)) != -1; partOs.write(buf, 0, readBytes));
fis2.close();
partOs.close();
PackageRelationship prs = slide.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
// blip.setEmbed(prs.getId());
picCur.setAttributeText(relName, prs.getId());
// maybe change the size a bit
// blipFill.getStretch().getFillRect().setL(<left padding in % (+/-)>)
}
picCur.dispose();
}
}
FileOutputStream fos = new FileOutputStream("test3.pptx");
pptx.write(fos);
fos.close();
}
}

Categories