精华内容
下载资源
问答
  • publicstaticvoidmain(String[]args){//模板、文件、图片路径StringworkPath=System.getProperty("user.dir")+"/static-utils/src/main/resources/word/";StringtemplateName="test.docx";Mapdatas=newHashMap()...

    public static void main(String[] args) {

    //模板、文件、图片路径

    String workPath=System.getProperty("user.dir") + "/static-utils/src/main/resources/word/";

    String templateName="test.docx";

    Map datas = new HashMap() {

    {

    //文本

    put("name","xiaoguo");

    put("sex","男");

    put("year","20200105");

    put("hello","xiaoguo写于2020年一月");

    //自定义表格

    RowRenderData header = RowRenderData.build(new TextRenderData("1C86EE", "姓名"), new TextRenderData("1C86EE", "学历"));

    RowRenderData row0 = RowRenderData.build("张三", "研究生");

    RowRenderData row1 = RowRenderData.build("李四", "博士");

    RowRenderData row2 = RowRenderData.build("王五", "博士后");

    put("tables", new MiniTableRenderData(header, Arrays.asList(row0, row1, row2)));

    //自定义有序列表

    put("testText", new NumbericRenderData(NumbericRenderData.FMT_DECIMAL, new ArrayList() {

    {

    add(new TextRenderData("Plug-in grammar"));

    add(new TextRenderData("Supports word text, header..."));

    add(new TextRenderData("Not just templates, but also style templates"));

    }

    }));

    //网落图片

    put("picture", new PictureRenderData(200, 150, ".jpg", BytePictureUtils.getUrlBufferedImage("https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=61c551093f6d55fbd1cb7e740c4b242f/d8f9d72a6059252d937820d3369b033b5ab5b9fd.jpg")));

    //本地图片

    put("picture2", new PictureRenderData(200, 150, ".jpg", BytePictureUtils.getLocalByteArray(new File(workPath + "c1.jpg"))));

    }

    };

    generateWord(datas, workPath + templateName, workPath);

    }

    /**

    * 通过word模板并生成word文档

    *

    * @param paramData    参数数据

    * @param templatePath word模板地址加模板文件名字

    * @param outFilePath  输出文件地址(不带文件名字)

    * @return 生成的word文件

    */

    public static File generateWord(Map paramData, String templatePath, String outFilePath) {

    String outFileName = "word_" + System.currentTimeMillis() + "_" + random.nextInt(100) + ".doc";

    return generateWord(paramData, templatePath, outFilePath, outFileName);

    }

    /**

    * 通过word模板并生成word文档

    *

    * @param paramData    参数数据

    * @param templatePath word模板地址加模板文件名字

    * @param outFilePath  输出文件地址(不带文件名字)

    * @param outFileName  输出文件名字

    * @return 生成的word文件

    */

    public static File generateWord(Map paramData, String templatePath, String outFilePath, String outFileName) {

    //判断输出文件路径和文件名是否含有指定后缀

    outFilePath = CommonUtil.addIfNoSuffix(outFilePath, "/", "\\");

    outFileName = CommonUtil.addIfNoSuffix(outFileName, ".doc", ".docx");

    //解析word模板

    XWPFTemplate template = XWPFTemplate.compile(templatePath).render(paramData);

    //输出文件

    FileOutputStream out = null;

    File outFile = new File(outFilePath + outFileName);

    try {

    out = new FileOutputStream(outFile);

    template.write(out);

    out.flush();

    } catch (IOException e) {

    log.error("生成word写入文件失败", e);

    } finally {

    if (template != null) {

    try {

    template.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    if (out != null) {

    try {

    out.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    return outFile;

    }

    展开全文
  • 刚到新的公司 就接到了 一个这样的需求 通过javaword模板填充数值变为一个word文件 (一想就想到了poi)并且要转为pdf格式 (这里就不做分析了 看下一篇有讲解) 然后就开始着手 我用的是poi的4.1 创建项目-建造...

    当前时间为2019-5-15 

    环境jdk8

    poi4.1(有很多别的包 防止后续来参考的弄错包 我给你们打包好了 放在下面链接中 )

    刚到新的公司 就接到了 一个这样的需求 通过java把word模板填充数值变为一个word文件 (一想就想到了poi)并且要转为pdf格式 (这里就不做分析了 看下一篇有讲解)

    然后就开始着手 我用的是poi的4.1

    创建项目-建造类-导入包-写方法


        

      /** 
          * 用一个docx文档作为模板,然后替换其中的内容,再写入目标文档中。 
          * 赵海鹏 2019-5-15
          * @throws Exception 
          */  
         
         @Test
         public void testTemplateWrite() throws Exception {  
            //获取值直接写入新的word中
            Map<String, Object> params = new HashMap<String, Object>();  
            params.put("", "");  
            params.put("", "");  
            params.put("", "");  
            params.put("", "");  
            params.put("", "");  
            params.put("", "");  
            String filePath = "D:\\需要读取的docx路径.docx";  
            InputStream is = new FileInputStream(filePath);  
            XWPFDocument doc = new XWPFDocument(is);  
            //替换段落里面的变量  
            this.replaceInPara(doc, params);  
            //替换表格里面的变量  
            this.replaceInTable(doc, params);  
            //最文末创建一个任意行表格
           //这里我加的这个动态获取是因为我们是web项目这个模板下面需要表格还是动态的 所以测试时候我就先随便给了两个值 h j。
            //控制h行j列
            int h=3;
            int j=5;
            XWPFTable table1 = doc.createTable(h, j);
            table1.setWidth(100);
            // 获取到刚刚插入的行
            XWPFTableRow row0 = table1.getRow(1);
            //合并单元格(这个是个公共方法 我写在了下面)
            mergeCellsHorizontal(table1,0,0,4);
            // 设置单元格内容
            row0.getCell(0).addParagraph().createRun().setText("这里是写表格的表头文字");
            row0.getCell(0).addParagraph().createRun().setBold(true);//加粗
            //设置样式
            XWPFTableRow row1 = table1.getRow(2);
            row1.getCell(0).addParagraph().createRun().setText("这里是写表格的表头文字");
            row1.getCell(0).addParagraph().createRun().setBold(true);
            row1.getCell(0).addParagraph().setAlignment(ParagraphAlignment.LEFT);
            row1.getCell(1).addParagraph().createRun().setText("这里是写表格的表头文字");
            row1.getCell(1).addParagraph().createRun().setBold(true);
            row1.getCell(1).addParagraph().setAlignment(ParagraphAlignment.LEFT);
            row1.getCell(2).addParagraph().createRun().setText("这里是写表格的表头文字");
            row1.getCell(2).addParagraph().createRun().setBold(true);
            row1.getCell(2).addParagraph().setAlignment(ParagraphAlignment.LEFT);
            row1.getCell(3).addParagraph().createRun().setText("这里是写表格的表头文字");
            row1.getCell(3).addParagraph().createRun().setBold(true);
            row1.getCell(3).addParagraph().setAlignment(ParagraphAlignment.LEFT);
            row1.getCell(4).addParagraph().createRun().setText("这里是写表格的表头文字");
            row1.getCell(4).addParagraph().createRun().setBold(true);//这是加粗
            row1.getCell(4).addParagraph().setAlignment(ParagraphAlignment.LEFT);//这是在表格中靠左
             //创建行,根据需要插入的数据添加新行,不处理表头 动态加表格 
            //for (int i = 1; i < tableList.size(); i++) {
            //    table.createRow();
            //}
            //输出word
            OutputStream os = new FileOutputStream("D:\\write.docx");  
            doc.write(os);  
            this.close(os);  
            this.close(is);  
         }  

    用这个导入代码块 格式乱了 还加了各别的说明 你们到时候自己改一下就行 

    下面是公共方法

    	//跨列合并单元格
    public  void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {  
    	        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {  
    	            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);  
    	            if ( cellIndex == fromCell ) {  
    	                // The first merged cell is set with RESTART merge value  
    	                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);  
    	            } else {  
    	                // Cells which join (merge) the first one, are set with CONTINUE  
    	                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);  
    	            }  
    	        }  
    	    }  
    		// word跨行并单元格
    		public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {  
    	        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {  
    	            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);  
    	            if ( rowIndex == fromRow ) {  
    	                // The first merged cell is set with RESTART merge value  
    	                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);  
    	            } else {  
    	                // Cells which join (merge) the first one, are set with CONTINUE  
    	                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);  
    	            }  
    	        }  
    	    } 
    	
         
         /** 
          * 替换段落里面的变量 
          * @param doc 要替换的文档 
          * @param params 参数 
          */  
         private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {  
            for( XWPFParagraph para : doc.getParagraphs()){
                this.replaceInPara(para, params); 
            }  
         }  
    
         /** 
          * 替换段落里面的变量 
          * @param para 要替换的段落 
          * @param params 参数 
          */  
         private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {  
            List<XWPFRun> runs;  
            Matcher matcher;  
            this.replaceText(para);//如果para拆分的不对,则用这个方法修改成正确的
            if (this.matcher(para.getParagraphText()).find()) {  
               runs = para.getRuns();  
               for (int i=0; i<runs.size(); i++) {  
                  XWPFRun run = runs.get(i);  
                  String runText = run.toString();  
                  matcher = this.matcher(runText);  
                  if (matcher.find()) {  
                      while ((matcher = this.matcher(runText)).find()) {  
                         runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));  
                      }  
                      //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,  
                      //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。  
                      para.removeRun(i);  
                      para.insertNewRun(i).setText(runText);  
                  }  
               }  
            }  
         }  
    
         /**
          * 合并runs中的内容
          * @param runs
          * @return
          */
         private List<XWPFRun> replaceText(XWPFParagraph para){
             List<XWPFRun> runs = para.getRuns();
             String str = "";
             boolean flag = false;
             for (int i=0; i<runs.size(); i++) {  
                 XWPFRun run = runs.get(i);  
                 String runText = run.toString();  
                 if( flag || runText.equals("${") ){
    
                     str = str + runText;
                     flag = true;
                     para.removeRun(i);
                     if( runText.equals("}") ){
                         flag = false;
                         para.insertNewRun(i).setText(str);  
                         str = "";
                     }
                     i--;
                 }
    
             }
    
             return runs;
         }
         /** 
          * 替换表格里面的变量 
          * @param doc 要替换的文档 
          * @param params 参数 
          */  
         private void replaceInTable(XWPFDocument doc, Map<String, Object> params) {  
            Iterator<XWPFTable> iterator = doc.getTablesIterator();  
            XWPFTable table;  
            List<XWPFTableRow> rows;  
            List<XWPFTableCell> cells;  
            List<XWPFParagraph> paras;  
            while (iterator.hasNext()) {  
               table = iterator.next();  
               rows = table.getRows();  
               for (XWPFTableRow row : rows) {  
                  cells = row.getTableCells();  
                  for (XWPFTableCell cell : cells) {  
                      paras = cell.getParagraphs();  
                      for (XWPFParagraph para : paras) {  
                         this.replaceInPara(para, params);  
                      }  
                  }  
               }  
            }  
         }  
    
         /** 
          * 正则匹配字符串 
          * @param str 
          * @return 
          */  
         private Matcher matcher(String str) {  
            Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);  
            Matcher matcher = pattern.matcher(str);  
            return matcher;  
         }  
    
         /** 
          * 关闭输入流 
          * @param is 
          */  
         private void close(InputStream is) {  
            if (is != null) {  
               try {  
                  is.close();  
               } catch (IOException e) {  
                  e.printStackTrace();  
               }  
            }  
         }  
    
         /** 
          * 关闭输出流 
          * @param os 
          */  
         private void close(OutputStream os) {  
            if (os != null) {  
               try {  
                  os.close();  
               } catch (IOException e) {  
                  e.printStackTrace();  
               }  
            }  
         }  
    

    把这些放到你项目 改改值参数 导入一下包就可以正常使用了 。

    有一些细节 强调下

    1.传值用${值} 这个最好在txt中写一下然后再放到模板上 不然很有可能出不来值 具体为什么 不详细说了。

    2.jar自己去下载可能会有遗漏。

    jar包下载地址(就要个幸苦分)!

    https://download.csdn.net/download/zhpboke/11179158

    展开全文
  • Java通过word模板配置书签生成word,这个是公司内部代码直接可以运行
  • 需求通过提前准备的word模板,渲染填充数据,生成新的加工好的word文件。(也试过使用Freemarker渲染数据,但是有个很大的弊端:使用Freemarker渲染的后文件会变大)用法POI的Maven依赖org.apache.poipoi3.8需要将模板...

    需求

    通过提前准备的word模板,渲染填充数据,生成新的加工好的word文件。(也试过使用Freemarker渲染数据,但是有个很大的弊端:使用Freemarker渲染的后文件会变大)

    用法

    POI的Maven依赖

    org.apache.poi

    poi

    3.8

    需要将模板参数设置成如下格式, 另存为word文档即可

    f7ada87a4082776ddd571b4a57ffce2d.png

    直接放代码,仅供参考

    import com.cloudlead.common.worker.client.exception.RestClientException;

    import org.apache.commons.lang.StringUtils;

    import org.apache.poi.openxml4j.opc.OPCPackage;

    import org.apache.poi.xwpf.usermodel.*;

    import org.apache.xmlbeans.XmlOptions;

    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;

    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;

    import java.io.*;

    import java.util.*;

    import java.util.regex.Matcher;

    import java.util.regex.Pattern;

    /*

    *

    * 文档处理类

    *

    * */

    public class WordTemplateUtil {

    /*从word模板 渲染参数 获取word文档

    * template 模板文件 params 参数 outputStream 输出流,

    */

    public static void wordRenderAndGetFromWordTemplate(File template, Mapparams, OutputStream outputStream)throws Exception{

    FileInputStream inputStream = new FileInputStream(template);

    XWPFDocument templateDoc = new XWPFDocument(inputStream);

    produce(templateDoc,params);

    templateDoc.write(outputStream);

    }

    /* 处理参数 生成doc */

    public static void produce(XWPFDocument templateDoc,Mapparams){

    Iteratoriterator = templateDoc.getParagraphsIterator();

    while(iterator.hasNext()){

    XWPFParagraph next = iterator.next();

    if (next.isEmpty()||!match(next.getParagraphText())){

    continue;

    }

    next.getRuns().forEach(

    run -> setNewTextforRun(run,params)

    );

    }

    }

    /*

    * 正则匹配 返回 matcher

    * */

    public static Matcher matcher(String text){

    Pattern pattern = Pattern.compile("\\$\\{(.+?)}", Pattern.CASE_INSENSITIVE);

    return pattern.matcher(text);

    }

    /*

    * 判定是否包匹配

    * */

    public static boolean match(String text){

    Matcher matcher = matcher(text);

    return matcher.find();

    }

    /*

    * 替换参数 设置新参数

    * */

    public static void setNewTextforRun(XWPFRun run,Mapparams){

    ListctTexts = run.getCTR().getTList();

    ctTexts.forEach(

    ctText->{

    String text = ctText.getStringValue();

    Matcher matcher = matcher(text);

    while(matcher.find()){

    String group = matcher.group();

    if (group.contains(" ")){

    throw new RestClientException("${}表达式不能包含空格");

    }

    String name = group.substring(2, group.length()-1);

    String value = params.get(name);

    value = value==null?"":value;

    if (text.equals(group)){

    text=value;

    }else{

    //转义

    String[] parts = text.split("\\$\\{"+name+"}");

    //length=1 分前后 设置参数值

    if (parts.length==1){

    String part = parts[0];

    text = text.indexOf(part)==0?(part+value):(value+part);

    }else{

    text = StringUtils.join(parts,value);

    }

    }

    }

    ctText.setStringValue(text);

    }

    );

    }

    }

    调用代码示例

    @GetMapping("/templateExport")

    public void exportContractFromTemplate() throws Exception{

    /*设置参数*/

    Mapparams = new HashMap<>();

    params.put("partyA","华为");

    params.put("partyB","新浪");

    params.put("contractNo","NO2019100506")

    params.put("signTime","2019年10月05日");

    String templatePath = "C:\\Users\\Administrator\\Desktop\\template.docx";

    response.setHeader("Content-Disposition", "attachment;filename=out.doc");

    response.setContentType("'application/msword';charset=UTF-8");

    response.setCharacterEncoding("UTF-8");

    WordTemplateUtil.wordRenderAndGetFromWordTemplate(

    new File(templatePath ), params, response.getOutputStream()

    );

    }

    展开全文
  • Java通过word模板导出word1.创建word模板文件,注意调整好格式,后期修改较为麻烦2.打开创建好的word模板,点击文件另存为,选择xml格式3.将生成的模板xml文件后缀改成ftl,例如:模板.xml-->模板.ftl4.在项目中...

    Java通过word模板导出word

    1.创建word模板文件,注意调整好格式,后期修改较为麻烦

    2.打开创建好的word模板,点击文件另存为,选择xml格式

    e0e73426e0d41fbe5db08e3603793375.png

    3.将生成的模板xml文件后缀改成ftl,例如:模板.xml-->模板.ftl

    4.在项目中引入freemarker依赖

    5.将模板.ftl文件放入项目resources下面的templates(自定义文件夹)

    6.编写代码程序。

    示例如下:

    public void exportReport(HttpServletResponse response) throws IOException, TemplateException {

    //map存储word需要的数据

    Map dataMap = new HashMap<>();

    //封装好的数据

    ReportDataDto dataForWord = getDataForWord(taskNo, isExport);

    //将数据指定key存储到map中

    dataMap.put("reportData", dataForWord);

    //配置对象

    Configuration configuration = new Configuration();

    //设置配置的字符编码为utf-8,避免字符集问题

    configuration.setDefaultEncoding("UTF-8");

    //获取resources下指定的文件夹路径,如果项目需要打成jar包,

    //此举很重要,别的方式可能无法获取到模板文件夹的相对路径

    configuration.setClassForTemplateLoading(this.getClass(), "/templates");

    // 获取模板实例,上行配置了模板文件所在路径

    Template t = configuration.getTemplate("模板.ftl", "utf-8");//以utf-8的编码读取ftl文件

    //设置响应类型为word

    response.setContentType("application/msword");

    //设置响应头,注意如果导出的word名含有汉字则需要将文件名

    //变成byte并且指定字符集为gbk,表示将GBK汉字转为byte

    //然后将其转为iso8859-1的字符串

    response.setHeader("Content-Disposition", "attachment;filename=\""

    + new String(("导出报告").getBytes("GBK"), "iso8859-1") + "\"");

    //此句非常关键,不然word文档全是乱码

    response.setCharacterEncoding("utf-8");

    PrintWriter out = response.getWriter();

    //使用数据填充模板

    t.process(dataMap, out);

    //以流的输出到浏览器,即下载

    out.close();

    }

    复制代码

    7.使用freemarker标签对模板.ftl文件进行数据渲染,例如:

    740b1e4955dc23f77d374a35a5d7b0d5.png

    tip:

    1.

    代表xml的段落,代表行,代表文本内容

    2.对于word中存在图片的情况,生成的模板.ftl将有这样一部分:

    9f1b6a4b52b93eb063f23eb7cedd4a5b.png

    找到 ${photo.zposs}

    标签,将里面的base64替换为${图片的base64}

    需要先将图片转为base64,下面提供一种方式

    public class Base64Util {

    /**

    *通过图片的URL转为base64

    */

    public static String getBase64ByImgUrl(String url){

    String suffix = url.substring(url.lastIndexOf(".") + 1);

    try {

    URL urls = new URL(url);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    Image image = Toolkit.getDefaultToolkit().getImage(urls);

    BufferedImage biOut = toBufferedImage(image);

    ImageIO.write(biOut, suffix, baos);

    String base64Str = encodeImage(baos.toByteArray());

    return base64Str;

    } catch (Exception e) {

    e.printStackTrace();

    return null;

    }

    }

    /**

    * 图片转字符串

    * @param image

    * @return

    */

    public static String encodeImage(byte[] image){

    BASE64Encoder decoder = new BASE64Encoder();

    return replaceEnter(decoder.encode(image));

    }

    }

    复制代码

    注意:

    1.使用frermarker标签时,尽量对数据做非空判断,避免出错

    2.如果模板一开始样式不对,可以在后来在模板中修改好样式,重新另存为xml文件,然后到ftl文件中找到此内容,替换

    展开全文
  • JAVA使用POI-TL通过Word模板生成Word文件

    万次阅读 热门讨论 2018-08-15 16:04:24
    技术背景 很多时候我们网站或者系统需要提供一些word文件,例如证明.docx或者订单....这里主要讲解如何通过一个制作好的word模板文件,通过数据填充,生成加工好的word文件。 官方网站 http://deepoove.com/...
  • 1、引用依赖 ...3、Word文件转换为模板 打开Word文件,另存为,XML格式文件,如图: 4、编写工具类 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.i...
  • java poi 通过模板生成word文档

    热门讨论 2014-07-22 17:10:34
    java使用poi,根据模板生成word文档.
  • java通过模板生成 word

    2019-08-05 01:12:49
    NULL 博文链接:https://huohu2005.iteye.com/blog/2040139
  • word替换原理:通过顺序查找word模板中的特殊字符标记,找到一个或多个就替换出响应的值,而表格的替换或者说生成是根据word中表格定义的序列来定位查找的,比如第一个表格的序列就是0,以此类推1,2,3...,所以...
  • java poi通过模板生成word文档

    千次阅读 2017-06-02 17:13:49
    里面说到使用模板的方式生成word文档,但是给出的代码并没有起效,这里我稍作了修改,这个是word文档模板方法操作工具类: [java] view plain copy print? package util; import org.apache...
  • date: 2017-04-15 21:34:56Java利用freemaker包来操作生成word模板。一个头疼的问题,了解了下xml。Java也是在学习的路上。需求自动化生成word报告,需要现有的word模板,选择后自动填入所需参数和计算后的结果。...
  • Java POI通过模板方法生成word文档

    千次阅读 2016-11-30 10:53:25
    Java POI通过模板方法生成word文档
  • 开始,同事用的freemarker实现了生成.doc的文件,但是我想生成.docx的文件,于是网上到处找资料,最终找到了解决方法,JAVA通过模板生成DOCX文档(2)这篇文章的帮助。还找了一些处理的文章,但是链接忘记了保存。下面...
  • 至此word生成就完事了,我写的有点粗,但是应该能看到的懂,代码没有经过重构,很乱,而且方法体应该还需要调整,但是不影响我们的功能实现。 总之 大家在做的过程中遇到什么问题,可以QQ:254432153 联系我,不过...
  • Java通过FreeMarker.jar模板生成word文档 原理:通过word的另存为xml文件,将xml文件转成freemarker模板文件,然后通过freemarker.jar将数据填充至模板,然后生成doc文件
  • word替换原理:通过顺序查找word模板中的特殊字符标记,找到一个或多个就替换出响应的值,而表格的替换或者说生成是根据word中表格定义的序列来定位查找的,比如第一个表格的序列就是0,以此类推1,2,3...,所以...
  • jacob它主要是一个java和com组件间的桥梁,所以jacob项目是java操作com接口的工具类,是采用的jni的方式,通过一个c++编写的dll文件来操作office文档。 Jacob使用 在使用jacob的时候,除了需要把jacob.jar...
  • 对企业合同word模版,可通过java 程序实现生成word文件,然后再通过word转成pdf实现。本实例的方案,可实现模版到word文件的转换。附件有代码和效果图。

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 233
精华内容 93
关键字:

java通过word模板生成

java 订阅