zoukankan      html  css  js  c++  java
  • docx4j基本操作

    最近需要用docx4j来对docx进行一些操作,用到的技术是docx4j,这个技术在国内其实用的不是很多,看了一些博主的文章,有些感悟,做了一些总结,如果有疑问或错误之处欢迎交流。

    创建包:

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();  

    保存包:

    wordMLPackage.save(new java.io.File("C://xxx.docx")); 

    得到主段落,并且输出/带样式输出:

    MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart(); 
    wordMLPackage.getMainDocumentPart().addParagraphOfText("Hello Word!");  
    wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Title", "Hello Word!");  wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Subtitle"," a subtitle!"); 

    创建表格并添加内容:

    ObjectFactory factory=Context.getWmlObjectFactory();  
    Tbl table = factory.createTbl();  
    Tr tableRow = factory.createTr();  
    Tc tableCell = factory.createTc();  
    tableCell.getContent().add(wordMLPackage.getMainDocumentPart().createParagraphOfText("Field 1"));  
    tableRow.getContent().add(tableCell);  
    table.getContent().add(tableRow);  
    wordMLPackage.getMainDocumentPart().addObject(table);  

    先创建一个工厂,(需要导入的包是org.docx4j.wml,导错的的话下面全错)创建表格,在创建行和单元格(tableCell),在单元格里添加你想要的内容,因为返回值是Object,只能通过这种方式传入数据,最后层层退回去,用add添加,最后在主段落添加。

    编辑表格样式:

    table.setTblPr(new TblPr());  
    CTBorder border = new CTBorder();  
    border.setColor("auto");  
    border.setSz(new BigInteger("4")); 
    TblBorders borders = new TblBorders();  
    borders.setBottom(border);  
    borders.setLeft(border);  
    borders.setInsideV(border);  
    table.getTblPr().setTblBorders(borders);  

    先创建table样式对象,在用CTBorder对象规定样式规范,用TblBorders对象将样式规范应用进去。

    创建 段落/运行块/运行块属性/文本 对象:

    ObjectFactory factory=Context.getWmlObjectFactory();  
    P paragraph = factory.createP();  
    Text text = factory.createText();  
    text.setValue(content);  
    R run = factory.createR();  
    run.getContent().add(text);  
    paragraph.getContent().add(run);  
    RPr runProperties = factory.createRPr(); 
    run.setRPr(runProperties);  
    tableCell.getContent().add(paragraph);  

    P是一个段落,Text是文本的值对象,R是一个运行块,负责便于将多个属性相同的Text对象统一操作,RPr是运行块的属性,可以对R对象进行操作。简单的说几个对象之间的关系可以这么理解:Tc tableCell > P paragraph > R run > Text text。其中,run.setRPr(RPr runProperties)可以设置块中属性。个人认为用开始的方法输入内容,在某种程度上是和上述代码做了一样的工作,效果相同。 
    加粗字体和调整字体大小:

    HpsMeasure size = new HpsMeasure();  
    size.setVal(new BigInteger("40"));  
    runProperties.setSz(size);  
    runProperties.setSzCs(size);  
    BooleanDefaultTrue b = new BooleanDefaultTrue();  
    b.setVal(true);  
    runProperties.setB(b);  

    思路是先创建各自的对象,设置对象的值为自己想要的情况,再用RPr的对象来set相应的属性。其中注意setVal中的值最后会被现实一半,所以只有字体20大小。

    纵向合并单元格:

    Tc tableCell = factory.createTc();  
    TcPr tableCellProperties = new TcPr();  
    VMerge merge = new VMerge();  
    merge.setVal("restart");  
    tableCellProperties.setVMerge(merge);  
    tableCell.setTcPr(tableCellProperties);  
    tableCell.getContent().add(wordMLPackage.getMainDocumentPart().createParagraphOfText(content));  
    row.getContent().add(tableCell);

    先创建单元格属性,再创建VMerge对象,如果设置merge则为向上合并,如果将merge属性设为restart则重新开始新的单元格。

    设置单元格宽度:

    TcPr tableCellProperties = new TcPr();
    TblWidth tableWidth = new TblWidth();
    tableWidth.setW(BigInteger.valueOf("50"));
    tableCellProperties.setTcW(tableWidth);
    tableCell.setTcPr(tableCellProperties);

    先创建单元格属性对象,创建Tblwidth对象并且设置宽度,用单元格属性对象通过方法调用Tblwidth对象。

    添加图片:

    File file = new File("c:\a.jpg");
    BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, file);
    int docPrId = 1;
    int cNvPrId = 2;
    Inline inline = imagePart.createImageInline("Filename hint","Alternative text", docPrId, cNvPrId, false);
    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);
    wordMLPackage.getMainDocumentPart().addObject(paragraph);

    打开文件,通过imagePart将图片读进去,现在图片被转换成二进制,为了能在文件中内联中显示出图片,调用函数将图片存在inline中。之后paragraph,run,drawing,用drawing读inline,方法同上。

    加载读入docx文件:

    WordprocessingMLPackage template = WordprocessingMLPackage.load(new File("c:\a.docx"));

    获取文档中所有内容(方法):

    private 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;  
    }  

    通过对类型的判断,将obj的内容分类读到List中,最后将内容按照列表的顺序贮存,如果obj是JAXB的一个实例就将他转型获取值,如果是和第二个参数的类型相同就添加,如果是ContentAccessor的一个对象,就将对象中的内容存到另外的一个列表中,再次调用自己将全部元素添加到原来的List中,返回一个List。

  • 相关阅读:
    线程中死锁的demo
    发布.net core程序碰到的问题
    .net core Identity学习(三) 第三方认证接入
    .net Identity学习(二)OAuth
    .net core Identity学习(一)注册登录
    Git常用操作
    log4net使用
    c#中的Quartz
    jquery中的deferred
    .net core应用部署在IIS上
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/7833911.html
Copyright © 2011-2022 走看看