java word 2007_java合并多个word 2007 文档 基于docx4j

1 packagecom.htsoft.oa.action.sjrh.tool;2

3 importjava.io.File;4 importjava.io.FileInputStream;5 importjava.io.FileOutputStream;6 importjava.io.IOException;7 importjava.io.InputStream;8 importjava.io.OutputStream;9 importjava.io.RandomAccessFile;10 importjava.nio.MappedByteBuffer;11 importjava.nio.channels.FileChannel;12 importjava.nio.channels.FileChannel.MapMode;13 importjava.text.SimpleDateFormat;14 importjava.util.ArrayList;15 importjava.util.Date;16 importjava.util.Iterator;17 importjava.util.List;18

19 importorg.apache.commons.io.IOUtils;20 importorg.docx4j.dml.wordprocessingDrawing.Inline;21 importorg.docx4j.jaxb.Context;22 importorg.docx4j.openpackaging.exceptions.Docx4JException;23 importorg.docx4j.openpackaging.packages.WordprocessingMLPackage;24 importorg.docx4j.openpackaging.parts.PartName;25 importorg.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;26 importorg.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;27 importorg.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;28 importorg.docx4j.relationships.Relationship;29 importorg.docx4j.wml.Br;30 importorg.docx4j.wml.CTAltChunk;31 importorg.docx4j.wml.Drawing;32 importorg.docx4j.wml.ObjectFactory;33 importorg.docx4j.wml.P;34 importorg.docx4j.wml.R;35 importorg.docx4j.wml.STBrType;36

37 importcom.alibaba.fastjson.JSONObject;38 importcom.htsoft.oa.action.sjrh.pojo.MergeResult;39

40 public classWordMergeUtils {41 private static ObjectFactory factory = newObjectFactory();42

43 /**

44 * 合并docx45 *46 *@paramstreams47 * 要合并的word文件的输入流48 *@parampath49 * 合并后的文件的路径50 *@return

51 *@throwsDocx4JException52 *@throwsIOException53 */

54 public static File mergeDocx(final List streams, String path) throwsDocx4JException, IOException {55

56 WordprocessingMLPackage target = null;57 final File generated = newFile(path);58

59 int chunkId = 0;60 Iterator it =streams.iterator();61 while(it.hasNext()) {62 InputStream is =it.next();63 if (is != null) {64 try{65 if (target == null) {66 //Copy first (master) document

67 OutputStream os = newFileOutputStream(generated);68 os.write(IOUtils.toByteArray(is));69 os.close();70

71 target =WordprocessingMLPackage.load(generated);72 } else{73 MainDocumentPart documentPart =target.getMainDocumentPart();74

75 //addPageBreak(documentPart);//另起一页,换页

76

77 insertDocx(documentPart, IOUtils.toByteArray(is), chunkId++);78 }79 } catch(Exception e) {80 e.printStackTrace();81 } finally{82 is.close();83 }84 }85 }86

87 if (target != null) {88 target.save(generated);89 //Docx4J.save(target, generated, Docx4J.FLAG_NONE);

90 returngenerated;91 } else{92 return null;93 }94 }95

96 //插入文档

97 private static void insertDocx(MainDocumentPart main, byte[] bytes, intchunkId) {98 try{99 AlternativeFormatInputPart afiPart = newAlternativeFormatInputPart(100 new PartName("/part" + chunkId + ".docx"));101 //afiPart.setContentType(new ContentType(CONTENT_TYPE));

102 afiPart.setBinaryData(bytes);103 Relationship altChunkRel =main.addTargetPart(afiPart);104

105 CTAltChunk chunk =Context.getWmlObjectFactory().createCTAltChunk();106 chunk.setId(altChunkRel.getId());107

108 main.addObject(chunk);109 } catch(Exception e) {110 e.printStackTrace();111 }112 }113

114 /**

115 * wordML转word,原文件不变,返回转换完成的word文件对象。116 *117 *@paramfile118 *@return

119 *@throwsDocx4JException120 *@throwsIOException121 */

122 public static File wordMLToWord(File file) throwsDocx4JException, IOException {123 WordprocessingMLPackage target =WordprocessingMLPackage.load(file);124 File temp = File.createTempFile(file.getName(), ".doc");125 target.save(temp);126 returntemp;127 }128

129 /**

130 * xml转docx,原文件不变,返回转换完成的word文件对象。131 *132 *@paramfile133 *@return

134 *@throwsDocx4JException135 *@throwsIOException136 */

137 public static File xmlToWord(File file) throwsDocx4JException, IOException {138 WordprocessingMLPackage target =WordprocessingMLPackage.load(file);139 File temp = File.createTempFile(file.getName(), ".doc");140 target.save(temp);141 returntemp;142 }143

144 /**

145 * 合并wordML文档146 *147 *@paramlist148 *@parampath149 *@throwsDocx4JException150 *@throwsIOException151 */

152 public static File mergeWordML(List list, String path) throwsDocx4JException, IOException {153 final List streams = new ArrayList();154 for (int i = 0; i < list.size(); i++) {155 File file =list.get(i);156 //file = WordMLUtil.wordMLToWord(file);//wordML转word

157 streams.add(newFileInputStream(file));158 }159 returnWordMergeUtils.mergeDocx(streams, path);160 }161

162 /**

163 * 把文件转换成Byte[] Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能164 *165 *@paramfilename166 *@return

167 *@throwsIOException168 */

169 public static byte[] fileToByteArray(String filename) throwsIOException {170

171 RandomAccessFile raf = null;172 FileChannel fc = null;173 try{174 raf = new RandomAccessFile(filename, "r");175 fc =raf.getChannel();176 MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0, fc.size()).load();177 System.out.println(byteBuffer.isLoaded());178 byte[] result = new byte[(int) fc.size()];179 if (byteBuffer.remaining() > 0) {180 byteBuffer.get(result, 0, byteBuffer.remaining());181 }182 returnresult;183 } catch(IOException e) {184 e.printStackTrace();185 throwe;186 } finally{187 try{188 fc.close();189 raf.close();190 } catch(IOException e) {191 e.printStackTrace();192 }193 }194 }195

196 /**

197 * Docx4j拥有一个由字节数组创建图片部件的工具方法, 随后将其添加到给定的包中. 为了能将图片添加 到一个段落中,198 * 我们需要将图片转换成内联对象. 这也有一个方法, 方法需要文件名提示, 替换文本, 两个id标识符和一个是嵌入还是链接到的指示作为参数.199 * 一个id用于文档中绘图对象不可见的属性, 另一个id用于图片本身不可见的绘制属性. 最后我们将内联 对象添加到段落中并将段落添加到包的主文档部件.200 *201 *@paramword202 * 需要编辑的文件203 *@paramimageList204 * 图片对象集合( 图片对象属性: url 图片文件路径 keyword 文档中的图片占位符 name 图片文件名 )205 *@throwsException206 * 不幸的createImageInline方法抛出一个异常(没有更多具体的异常类型)207 */

208 public static void addImageToPackage(File word, List imageList) throwsException {209

210 WordprocessingMLPackage wordMLPackage =WordprocessingMLPackage.load(word);211

212 for (int i = 0; i < imageList.size(); i++) {213 JSONObject image =imageList.get(i);214

215 byte[] bytes = fileToByteArray(image.getString("url"));216

217 BinaryPartAbstractImage imagePart =BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);218

219 int docPrId = 1;220 int cNvPrId = 2;221 Inline inline = imagePart.createImageInline(image.getString("name"), image.getString("keyword"), docPrId,222 cNvPrId, false);223

224 P paragraph =addInlineImageToParagraph(inline);225

226 wordMLPackage.getMainDocumentPart().addObject(paragraph);227 }228

229 wordMLPackage.save(word);230 }231

232 /**

233 * Docx4j拥有一个由字节数组创建图片部件的工具方法, 随后将其添加到给定的包中. 为了能将图片添加 到一个段落中,234 * 我们需要将图片转换成内联对象. 这也有一个方法, 方法需要文件名提示, 替换文本, 两个id标识符和一个是嵌入还是链接到的指示作为参数.235 * 一个id用于文档中绘图对象不可见的属性, 另一个id用于图片本身不可见的绘制属性. 最后我们将内联 对象添加到段落中并将段落添加到包的主文档部件.236 *237 *@paramwordFilePath238 * 文件路径239 *@paramimageList240 * 图片对象集合( 图片对象属性: url 图片文件路径 keyword 文档中的图片占位符 name 图片文件名 )241 *@throwsException242 * 不幸的createImageInline方法抛出一个异常(没有更多具体的异常类型)243 */

244 public static void addImageToPackage(String wordFilePath, List imageList) throwsException {245 addImageToPackage(newFile(wordFilePath), imageList);246 }247

248 /**

249 * 创建一个对象工厂并用它创建一个段落和一个可运行块R. 然后将可运行块添加到段落中. 接下来创建一个图画并将其添加到可运行块R中. 最后我们将内联250 * 对象添加到图画中并返回段落对象.251 *252 *@paraminline253 * 包含图片的内联对象.254 *@return包含图片的段落255 */

256 private staticP addInlineImageToParagraph(Inline inline) {257 //添加内联对象到一个段落中

258 P paragraph =factory.createP();259 R run =factory.createR();260 paragraph.getContent().add(run);261 Drawing drawing =factory.createDrawing();262 run.getContent().add(drawing);263 drawing.getAnchorOrInline().add(inline);264 returnparagraph;265 }266

267 /**

268 * 文档结尾添加一个空白页269 *270 *@throwsDocx4JException271 */

272 public static void addPageBreak(File word) throwsDocx4JException {273

274 WordprocessingMLPackage wordMLPackage =WordprocessingMLPackage.load(word);275

276 MainDocumentPart documentPart =wordMLPackage.getMainDocumentPart();277

278 Br breakObj = newBr();279 breakObj.setType(STBrType.PAGE);280

281 P paragraph =factory.createP();282 paragraph.getContent().add(breakObj);283 documentPart.getJaxbElement().getBody().getContent().add(paragraph);284 wordMLPackage.save(word);285 }286

287 /**

288 * 文档结尾添加一个空白页289 *290 *@throwsDocx4JException291 */

292 public static voidaddPageBreak(MainDocumentPart documentPart) {293 Br breakObj = newBr();294 breakObj.setType(STBrType.PAGE);295

296 P paragraph =factory.createP();297 paragraph.getContent().add(breakObj);298 documentPart.getJaxbElement().getBody().getContent().add(paragraph);299 }300

301 /**

302 * 文档结尾添加一个空白页303 *304 *@throwsDocx4JException305 */

306 public static void addPageBreak(String wordFilePath) throwsDocx4JException {307 addPageBreak(newFile(wordFilePath));308 }309

310 /**

311 * 合并word文档 接口方法312 *313 *@paramsourceFiles待合并文件314 *@parammergedFileName合并后的文件名称315 *@throwsException316 */

317 public static MergeResult merge(String djxh, ListsourceFiles, String mergedFileName) {318

319 if (djxh == null ||djxh.isEmpty()) {320 return new MergeResult(-1, null, "登记序号为空!", null);321 } else if (sourceFiles == null || sourceFiles.size() <= 0) {322 return new MergeResult(-1, null, "待合并文件路径为空!", null);323 }324

325 try{326 List files = new ArrayList();327 for(String filePath : sourceFiles) {328 File file = newFile(filePath);329 files.add(file);330 }331

332 //保存基础路径

333 String path = "";334 if ("1".equals(WordStaticFileds.open_Fixed_path)) {335 //创建固定路径

336 path = WordStaticFileds.create_word_path + "word/fixed/" +djxh;337 } else{338 //创建不固定路径

339 path = WordStaticFileds.create_word_path + "word/notFixed/"

340 + new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" +djxh;341 }342

343 if (mergedFileName == null ||mergedFileName.isEmpty()) {344 if (files.size() > 0) {345 String oldName = files.get(0).getName();346 int lastIndexOf = oldName.lastIndexOf(".");347 if (lastIndexOf > 0) {348 mergedFileName = oldName.substring(0, lastIndexOf) + "-合并后.docx";349 }350 }351 }352

353 File mergedfile = newFile(path);354

355 if (!mergedfile.exists()) {356 mergedfile.mkdirs();357 }358

359 String mergedFullPath = path + "/" +mergedFileName;360 File mergeWordML =WordMergeUtils.mergeWordML(files, mergedFullPath);361

362

363 return new MergeResult(0, mergeWordML, "合并word文件成功!", mergeWordML.getAbsolutePath());364 } catch(Exception e) {365 return new MergeResult(-1, null, "合并word文件出错!错误信息:" + e.getMessage(), null);366 }367

368 }369 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值