现有这么个需求,现有的文档里有个编号,需要使用条码图片替代,编号就是一串数字。生成条码的问题简单,问题是现有的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不知道从哪儿查起