All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.craigburke.document.builder.WordDocument.groovy Maven / Gradle / Ivy
package com.craigburke.document.builder
import groovy.xml.StreamingMarkupBuilder
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
/**
* Helper class for writing document in OOXML format
* @author Craig Burke
*/
class WordDocument {
private static final String ROOT_RELATIONSHIP_FILE = '_rels/.rels'
private static final String CONTENT_FOLDER = 'word'
private static final String IMAGE_FOLDER = 'media'
private static final String XML_HEADER = ''
private static final DOCUMENT_NAMESPACES = [
w:'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
a:'http://schemas.openxmlformats.org/drawingml/2006/main',
pic:'http://schemas.openxmlformats.org/drawingml/2006/picture',
wp:'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',
r:'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
]
Map documentParts = [:]
List contentTypes = []
ZipOutputStream zipStream
List contentTypeOverrides = []
WordDocument(OutputStream out) {
documentParts[DocumentPartType.ROOT.value] = new DocumentPart(type:DocumentPartType.ROOT)
documentParts[DocumentPartType.DOCUMENT.value] = new DocumentPart(type:DocumentPartType.DOCUMENT)
zipStream = new ZipOutputStream(out)
addRelationship(
"${CONTENT_FOLDER}/${DocumentPartType.DOCUMENT.fileName}",
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
DocumentPartType.ROOT
)
contentTypes << new ContentType(
extension:'rels',
type:'application/vnd.openxmlformats-package.relationships+xml')
contentTypes << new ContentType(extension:'xml', type:'application/xml')
contentTypes << new ContentType(extension:'png', type:'image/png')
contentTypes << new ContentType(extension:'jpg', type:'image/jpeg')
contentTypes << new ContentType(extension:'jpeg', type:'image/jpeg')
}
String addRelationship(String target, String type, DocumentPartType part) {
def currentRelationships = documentParts[part.value].relationships
String id = "rId${currentRelationships.size() + 1}"
currentRelationships << new Relationship(id:id, target:target, type:type)
id
}
void write() {
writeDocPropsFiles()
writeRelationships()
writeContentTypes()
zipStream.close()
}
void writeDocPropsFiles() {
zipStream.putNextEntry(new ZipEntry('docProps/app.xml'))
zipStream << new StreamingMarkupBuilder().bind { builder ->
mkp.yieldUnescaped(XML_HEADER)
namespaces << ['':'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties']
Properties {
Application('Groovy Document Builder')
}
}
zipStream.closeEntry()
contentTypeOverrides << new ContentTypeOverride(
partName:'/docProps/app.xml',
contentType:'application/vnd.openxmlformats-officedocument.extended-properties+xml'
)
zipStream.putNextEntry(new ZipEntry('docProps/core.xml'))
zipStream << new StreamingMarkupBuilder().bind { builder ->
mkp.yieldUnescaped(XML_HEADER)
namespaces << [
'':'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
'cp':'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
'dc':'http://purl.org/dc/elements/1.1/',
'dcterms':'http://purl.org/dc/terms/',
'xsi':'http://www.w3.org/2001/XMLSchema-instance'
]
coreProperties {
dc.creator('Groovy Document Builder')
}
}
zipStream.closeEntry()
contentTypeOverrides << new ContentTypeOverride(
partName:'/docProps/core.xml',
contentType:'conteapplication/vnd.openxmlformats-package.core-properties+xml'
)
}
def generateDocument(Closure documentClosure) {
zipStream.putNextEntry(new ZipEntry("${CONTENT_FOLDER}/${DocumentPartType.DOCUMENT.fileName}"))
zipStream << new StreamingMarkupBuilder().bind { builder ->
mkp.yieldUnescaped(XML_HEADER)
namespaces << DOCUMENT_NAMESPACES
documentClosure.delegate = builder
documentClosure(builder)
}.toString()
zipStream.closeEntry()
addImageFiles()
}
String generateHeader(Closure headerClosure) {
documentParts[DocumentPartType.HEADER.value] = new DocumentPart(type:DocumentPartType.HEADER)
zipStream.putNextEntry(new ZipEntry("${CONTENT_FOLDER}/${DocumentPartType.HEADER.fileName}"))
zipStream << new StreamingMarkupBuilder().bind { builder ->
mkp.yieldUnescaped(XML_HEADER)
namespaces << DOCUMENT_NAMESPACES
headerClosure.delegate = builder
headerClosure(builder)
}.toString()
zipStream.closeEntry()
addRelationship(
DocumentPartType.HEADER.fileName,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header',
DocumentPartType.DOCUMENT
)
}
String generateFooter(Closure footerClosure) {
documentParts[DocumentPartType.FOOTER.value] = new DocumentPart(type:DocumentPartType.FOOTER)
zipStream.putNextEntry(new ZipEntry("${CONTENT_FOLDER}/${DocumentPartType.FOOTER.fileName}"))
zipStream << new StreamingMarkupBuilder().bind { builder ->
mkp.yieldUnescaped(XML_HEADER)
namespaces << DOCUMENT_NAMESPACES
footerClosure.delegate = builder
footerClosure(builder)
}.toString()
zipStream.closeEntry()
addRelationship(
DocumentPartType.FOOTER.fileName,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer',
DocumentPartType.DOCUMENT
)
}
private addImageFiles() {
documentParts.each { String name, DocumentPart part ->
part.images.each { image ->
zipStream.putNextEntry(new ZipEntry("${CONTENT_FOLDER}/${IMAGE_FOLDER}/${image.name}"))
zipStream << image.data
zipStream.closeEntry()
}
}
}
String addImage(String name, byte[] imageData, DocumentPartType partType) {
String id = addRelationship(
"${IMAGE_FOLDER}/${name}",
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
partType
)
documentParts[partType.value].images << [id:id, name:name, data:imageData]
id
}
private void writeRelationships() {
documentParts.each { String name, DocumentPart documentPart ->
writeRelationshipsForPart(documentPart.type)
}
}
private void writeRelationshipsForPart(DocumentPartType documentPart) {
String fileLocation
if (documentPart == DocumentPartType.ROOT) {
fileLocation = ROOT_RELATIONSHIP_FILE
}
else {
fileLocation = "${CONTENT_FOLDER}/_rels/${documentPart.fileName}.rels"
}
zipStream.putNextEntry(new ZipEntry(fileLocation))
zipStream << new StreamingMarkupBuilder().bind {
mkp.yieldUnescaped(XML_HEADER)
namespaces << ['':'http://schemas.openxmlformats.org/package/2006/relationships']
Relationships {
documentParts[documentPart.value].relationships.each { Relationship relationship ->
Relationship(Id:relationship.id, Target:relationship.target, Type:relationship.type)
}
}
}.toString()
zipStream.closeEntry()
}
private void writeContentTypes() {
zipStream.putNextEntry(new ZipEntry('[Content_Types].xml'))
zipStream << new StreamingMarkupBuilder().bind {
mkp.yieldUnescaped(XML_HEADER)
namespaces << ['':'http://schemas.openxmlformats.org/package/2006/content-types']
Types {
contentTypes.each { ContentType type ->
Default(Extension:type.extension, ContentType:type.type)
}
def nonRootParts = documentParts.findAll { it.key != DocumentPartType.ROOT.value }
nonRootParts.each { String name, DocumentPart documentPart ->
Override(PartName:"/${CONTENT_FOLDER}/${documentPart.type.fileName}",
ContentType:documentPart.type.contentType)
}
contentTypeOverrides.each { ContentTypeOverride override ->
Override(PartName:override.partName, ContentType:override.contentType)
}
}
}.toString()
zipStream.closeEntry()
}
}