public class DocxService { private static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; public InputStream mergeDocx(final List<InputStream> streams) throws Docx4JException, IOException { WordprocessingMLPackage target = null; final File generated = File.createTempFile("generated", ".docx"); int chunkId = 0; Iterator<InputStream> it = streams.iterator(); while (it.hasNext()) { InputStream is = it.next(); if (is != null) { if (target == null) { // Copy first (master) document OutputStream os = new FileOutputStream(generated); os.write(IOUtils.toByteArray(is)); os.close(); target = WordprocessingMLPackage.load(generated); } else { // Attach the others (Alternative input parts) insertDocx(target.getMainDocumentPart(), IOUtils.toByteArray(is), chunkId++); } } } if (target != null) { target.save(generated); return new FileInputStream(generated); } else { return null; } } private static void insertDocx(MainDocumentPart main, byte[] bytes, int chunkId) { try { AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/part" + chunkId + ".docx")); afiPart.setContentType(new ContentType(CONTENT_TYPE)); afiPart.setBinaryData(bytes); Relationship altChunkRel = main.addTargetPart(afiPart); CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk(); chunk.setId(altChunkRel.getId()); main.addObject(chunk); } catch (Exception e) { e.printStackTrace(); } } }Note: Generated file can be opened only in Microsoft Office 2007 or newer (Win/Mac). OpenOffice/LibreOffice render only the master document, ignorind attached ones.
Monday, July 4, 2011
Merge .docx files in Java using docx4j
This code is used in one of the projects I was attached to. The first source file (stream) is used as master document, so, all styles defined in this one will be applied to subdocument (incl. headers and footers).
Subscribe to:
Posts (Atom)