现有这么个需求,现有的文档里有个编号,需要使用条码图片替代,编号就是一串数字。生成条码的问题简单,问题是现有的word文档全部使用rtf模板cell里面写的标示符如,客户姓名:custName 然后后台使用map.put("custName","张三");这种方式将rtf里面的标示为替换后输出word文档;
第一种方案:使用itext,但是这个jar只能新生成,对于复杂word就显得有点麻烦,因为里面行列表格需要全部使用代码拼装。
第二种:图片存放在word里面实际东西也是字符串,但是这个字符串的规则无法得知,如果能知道这个图片的字符串格式就可以不改代码,将图片生成字符串去替换就可以。所以现在问题的关键在图片存放在word文档的字符串规则。
有过类似问题的朋友指点一下,要是有好的方案请共享一下,谢谢!
I am sorry,忘了贴这个方法了。
/***************************************************************************** * 获得段落中字符串的值 * @param obj 某个段落 * @return String 段落中文字 *****************************************************************************/ public static String getParagraphStrValue(Object obj){ if(obj == null){return null;} StringBuffer sb = new StringBuffer(256); if (obj instanceof ContentAccessor){ List<Object> texts = getAllElementFromObject(obj, Text.class); for (Object child : texts) { sb.append(((Text)child).getValue()); } }else if(obj instanceof JAXBElement){ sb.append(((Text)obj).getValue()); } return sb.toString(); }
/***************************************************************************** * 替换图表 * @param obj 需要替换的paragraph * @param imgPath 图片路径 * @param wordMLPackage wordMLPackage *****************************************************************************/ public static void replaceChart(Object obj,String imgPath,WordprocessingMLPackage wordMLPackage){ if(obj == null || imgPath == null){return;} List<Object> texts = getAllElementFromObject(obj, Text.class); for (Object t : texts) { Text content = (Text) t; content.setValue(""); } File file = new File(imgPath); InputStream is = null; try { is = new FileInputStream(file ); long length = file.length(); if (length > Integer.MAX_VALUE) { return; } byte[] bytes = new byte[(int)length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { return; } String filenameHint = null; String altText = null; int id1 = 0; int id2 = 1; newImage(wordMLPackage, (P)obj, bytes, filenameHint, altText, id1, id2); } catch (Exception e) { //e.printStackTrace(); }finally{ if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } //添加图片 private static void newImage( WordprocessingMLPackage wordMLPackage,P p,byte[] bytes,String filenameHint, String altText, int id1, int id2) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); Inline inline = imagePart.createImageInline( filenameHint, altText,id1, id2, false); // Now add the inline in w:p/w:r/w:drawing ObjectFactory factory = Context.getWmlObjectFactory(); R run = factory.createR(); p.getContent().add(run); PPr ppr = factory.createPPr(); Jc jc = factory.createJc(); Ind ind = factory.createPPrBaseInd(); ind.setFirstLine(new BigInteger("0")); ind.setFirstLineChars(new BigInteger("0")); jc.setVal(JcEnumeration.LEFT); ppr.setJc(jc); ppr.setInd(ind); p.setPPr(ppr); Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); }######回复 @bigtiger02 : 恩,这是个麻烦事儿,用你说的第一种办法可行吗?######回复 @anyine : jacob是一个java-COM中间件.通过这个组件你可以在Java应用程序中调用COM组件和Win32程序库,只能在windows环境下使用######回复 @bigtiger02 : 我的web运行在linux下 jacob还有效吗######回复 @bigtiger02 : 3Q 我先看看...######回复 @anyine : 2003的话,我以前用的是jacob来进行替换,但是觉得并不是那么好用,给个jacob例子: http://blog.csdn.net/lulongzhou_llz/article/details/6701918######
/***************************************************************************** * 替换图表 * @param obj 需要替换的paragraph * @param imgPath 图片路径 * @param wordMLPackage wordMLPackage *****************************************************************************/ public static void replaceChart(Object obj,String imgPath,WordprocessingMLPackage wordMLPackage){ if(obj == null || imgPath == null){return;} List<Object> texts = getAllElementFromObject(obj, Text.class); for (Object t : texts) { Text content = (Text) t; content.setValue(""); } File file = new File(imgPath); InputStream is = null; try { is = new FileInputStream(file ); long length = file.length(); if (length > Integer.MAX_VALUE) { return; } byte[] bytes = new byte[(int)length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { return; } String filenameHint = null; String altText = null; int id1 = 0; int id2 = 1; newImage(wordMLPackage, (P)obj, bytes, filenameHint, altText, id1, id2); } catch (Exception e) { //e.printStackTrace(); }finally{ if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } //添加图片 private static void newImage( WordprocessingMLPackage wordMLPackage,P p,byte[] bytes,String filenameHint, String altText, int id1, int id2) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); Inline inline = imagePart.createImageInline( filenameHint, altText,id1, id2, false); // Now add the inline in w:p/w:r/w:drawing ObjectFactory factory = Context.getWmlObjectFactory(); R run = factory.createR(); p.getContent().add(run); PPr ppr = factory.createPPr(); Jc jc = factory.createJc(); Ind ind = factory.createPPrBaseInd(); ind.setFirstLine(new BigInteger("0")); ind.setFirstLineChars(new BigInteger("0")); jc.setVal(JcEnumeration.LEFT); ppr.setJc(jc); ppr.setInd(ind); p.setPPr(ppr); Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); }
回复 @bigtiger02 : 我现在能读取,能写入了。但是不知道用哪个方法指定写入的位置或者替换。
private static void addImageToPackage(WordprocessingMLPackage wordMLPackage,
byte[] bytes) throws Exception {
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
int docPrId = 1;
int cNvPrId = 2;
Inline inline = imagePart.createImageInline("Filename hint","Alternative text", docPrId, cNvPrId, false);
P paragraph = addInlineImageToParagraph(inline);
wordMLPackage.getMainDocumentPart().addObject(paragraph);
}
/**
* 创建一个对象工厂并用它创建一个段落和一个可运行块R.
* 然后将可运行块添加到段落中. 接下来创建一个图画并将其添加到可运行块R中. 最后我们将内联
* 对象添加到图画中并返回段落对象.
*
* @param inline 包含图片的内联对象.
* @return 包含图片的段落
*/
private static P addInlineImageToParagraph(Inline inline) {
// 添加内联对象到一个段落中
ObjectFactory factory = new ObjectFactory();
P paragraph = factory.createP();
R run = factory.createR();
paragraph.getContent().add(run);
Drawing drawing = factory.createDrawing();
run.getContent().add(drawing);
drawing.getAnchorOrInline().add(inline);
return paragraph;
}
麻烦你指点一下呢
你可以用一段文字进行标记,然后查找将这段文字替换成图片即可。
world操作方法:
//拷贝文件 dstUrlTmp = copyFile(modelUrl,dstUrl); //开始wordMLPackage = DocxUtils.load(dstUrlTmp); document = wordMLPackage.getMainDocumentPart(); //替换字符串、表格以及图片 replace(DocxUtils.getAllElementFromObject(document,P.class)); //保存 DocxUtils.save(wordMLPackage, dstUrl);replace方法:
//执行替换 private void replace(List<Object> paragraphs){ final int pSize = paragraphs.size(); for (int i = 0; i < pSize; i++) { Object obj = paragraphs.get(i); String text = DocxUtils.getParagraphStrValue(obj); Set<String> jsons = getMatchStr("\\{(\"\\w+\":\"?\\w+\"?,*){1,}\\}", StringUtil.replace(text, CN_CHARS, CN_REPLACE_CHARS)); if(CollectionUtils.isNotEmpty(jsons)){//不为空则进行分发 for (String s : jsons) { DOCJsonObject jsonObject = null; try { jsonObject = new Gson().fromJson(s, DOCJsonObject.class); } catch (Exception e) { e.printStackTrace(); } if(jsonObject == null){ continue; }else{ DocxUtils.replaceChart(obj, imgPath, wordMLPackage); } } } } }替换方法见一楼
/***************************************************************************** * 查找JAXBElement元素 * @param obj 查找目标 * @param toSearch 查找类的class * @return List<Object> *****************************************************************************/ public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) { List<Object> result = new ArrayList<Object>(); if (obj instanceof JAXBElement){ obj = ((JAXBElement<?>) obj).getValue(); } if (obj.getClass().equals(toSearch)){ result.add(obj); }else if (obj instanceof ContentAccessor) { List<?> children = ((ContentAccessor) obj).getContent(); for (Object child : children) { result.addAll(getAllElementFromObject(child, toSearch)); } } return result; }
你可以用一段文字进行标记,然后查找将这段文字替换成图片即可。
world操作方法:
//拷贝文件 dstUrlTmp = copyFile(modelUrl,dstUrl); //开始wordMLPackage = DocxUtils.load(dstUrlTmp); document = wordMLPackage.getMainDocumentPart(); //替换字符串、表格以及图片 replace(DocxUtils.getAllElementFromObject(document,P.class)); //保存 DocxUtils.save(wordMLPackage, dstUrl);replace方法:
//执行替换 private void replace(List<Object> paragraphs){ final int pSize = paragraphs.size(); for (int i = 0; i < pSize; i++) { Object obj = paragraphs.get(i); String text = DocxUtils.getParagraphStrValue(obj); Set<String> jsons = getMatchStr("\\{(\"\\w+\":\"?\\w+\"?,*){1,}\\}", StringUtil.replace(text, CN_CHARS, CN_REPLACE_CHARS)); if(CollectionUtils.isNotEmpty(jsons)){//不为空则进行分发 for (String s : jsons) { DOCJsonObject jsonObject = null; try { jsonObject = new Gson().fromJson(s, DOCJsonObject.class); } catch (Exception e) { e.printStackTrace(); } if(jsonObject == null){ continue; }else{ DocxUtils.replaceChart(obj, imgPath, wordMLPackage); } } } } }替换方法见一楼
/***************************************************************************** * 查找JAXBElement元素 * @param obj 查找目标 * @param toSearch 查找类的class * @return List<Object> *****************************************************************************/ public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) { List<Object> result = new ArrayList<Object>(); if (obj instanceof JAXBElement){ obj = ((JAXBElement<?>) obj).getValue(); } if (obj.getClass().equals(toSearch)){ result.add(obj); }else if (obj instanceof ContentAccessor) { List<?> children = ((ContentAccessor) obj).getContent(); for (Object child : children) { result.addAll(getAllElementFromObject(child, toSearch)); } } return result; }
我就想知道,我怎么通过我文档里的一段标示位找到一个对象来替换
P paragraph = 这里我想找到我要替换的东西;
你可以用一段文字进行标记,然后查找将这段文字替换成图片即可。
world操作方法:
//拷贝文件 dstUrlTmp = copyFile(modelUrl,dstUrl); //开始wordMLPackage = DocxUtils.load(dstUrlTmp); document = wordMLPackage.getMainDocumentPart(); //替换字符串、表格以及图片 replace(DocxUtils.getAllElementFromObject(document,P.class)); //保存 DocxUtils.save(wordMLPackage, dstUrl);replace方法:
//执行替换 private void replace(List<Object> paragraphs){ final int pSize = paragraphs.size(); for (int i = 0; i < pSize; i++) { Object obj = paragraphs.get(i); String text = DocxUtils.getParagraphStrValue(obj); Set<String> jsons = getMatchStr("\\{(\"\\w+\":\"?\\w+\"?,*){1,}\\}", StringUtil.replace(text, CN_CHARS, CN_REPLACE_CHARS)); if(CollectionUtils.isNotEmpty(jsons)){//不为空则进行分发 for (String s : jsons) { DOCJsonObject jsonObject = null; try { jsonObject = new Gson().fromJson(s, DOCJsonObject.class); } catch (Exception e) { e.printStackTrace(); } if(jsonObject == null){ continue; }else{ DocxUtils.replaceChart(obj, imgPath, wordMLPackage); } } } } }替换方法见一楼
/***************************************************************************** * 查找JAXBElement元素 * @param obj 查找目标 * @param toSearch 查找类的class * @return List<Object> *****************************************************************************/ public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) { List<Object> result = new ArrayList<Object>(); if (obj instanceof JAXBElement){ obj = ((JAXBElement<?>) obj).getValue(); } if (obj.getClass().equals(toSearch)){ result.add(obj); }else if (obj instanceof ContentAccessor) { List<?> children = ((ContentAccessor) obj).getContent(); for (Object child : children) { result.addAll(getAllElementFromObject(child, toSearch)); } } return result; }
我就想知道,我怎么通过我文档里的一段标示位找到一个对象来替换
P paragraph = 这里我想找到我要替换的东西;
我之前的是新添加了一个段落来写入图片 现在我想用文档里面现有的地方来写入图片
private static P addInlineImageToParagraph(Inline inline) { // 添加内联对象到一个段落中 ObjectFactory factory = new ObjectFactory(); P paragraph = factory.createP(); R run = factory.createR(); paragraph.getContent().add(run); Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); return paragraph; }
DocxUtils.getAllElementFromObject(document,P.class)
可以读取word里面所有的段落,用
DocxUtils.getParagraphStrValue(obj);
可以读取这个段落的字符串,若这个段落的字符串equals("image"),则进行替换
DocxUtils.replaceChart(obj, imgPath, wordMLPackage);######
DocxUtils.getAllElementFromObject(document,P.class)
可以读取word里面所有的段落,用
DocxUtils.getParagraphStrValue(obj);
可以读取这个段落的字符串,若这个段落的字符串equals("image"),则进行替换
DocxUtils.replaceChart(obj, imgPath, wordMLPackage);
DocxUtils.getParagraphStrValue 说了半天我就是不知道你这儿是怎么写的啊,查他的API不知道从哪儿查起
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。