使用poi-tl导出动态word模板,包含折线图、柱状图、饼状图

1 依赖引入

      <dependency>
          <groupId>com.deepoove</groupId>
          <artifactId>poi-tl</artifactId>
          <version>1.8.2</version>
    </dependency>

2 新建word模板

Word模板中所有变量以{{开头,以}}结尾,不同内容变量声明如下

1){{template}}    普通文本,渲染数据为:String或者TextRenderData

2){{#template}}   表格,渲染数据为:TableRenderData

3)当生成图表时,新建图表—>右键编辑替换文字—>{{barLineCharts}} 图表变量,如下图(可能不同版本编辑替换文字位置不同。)

3 java获取数据,生成word

1)声明模板的位置:

XWPFTemplate template = XWPFTemplate.compile("./src/main/resources/templates/template.docx");

2)导出word路径,名称

FileOutputStream out = new FileOutputStream("./src/main/resources/templates/output_"+String.valueOf(Math.random())+".docx");

 3)填充数据

//声明map存放模板中的内容
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("title","hello world");
//Logger.info("hello");
/*测试文本插入------------------------------*/
//先定义文本对象
TextRenderData textRenderData = new TextRenderData();
//设置文本内容
textRenderData.setText("张三");
//设置文本格式
Style style = new Style();
style.setBold(true);
style.setColor("000F00");
style.setFontSize(20);
textRenderData.setStyle(style);
//将文本数据和模板中变量对应
data.put("name", textRenderData);
/* 测试表格插入---------------------------------------*/
		//定义表格的头
		//方式一
		//RowRenderData headerData = RowRenderData.build("电灯名称","使用率");
		//设置样式
		TableStyle tStyle = new TableStyle();
		tStyle.setBackgroundColor("87CEEB");
		//表头方式二
		/*RowRenderData headerData = RowRenderData.build(
				new TextRenderData("FFFFFF","仪器名称"),new TextRenderData("FFFFFF","使用率"));*/
		//表头方式三
		
		List<CellRenderData> listCellRenderDatas =new ArrayList<CellRenderData>();
		CellRenderData cellRenderData1 = new CellRenderData();
		cellRenderData1.setCellText(new TextRenderData("000000","电灯名称"));
		listCellRenderDatas.add(cellRenderData1);
		CellRenderData cellRenderData2 = new CellRenderData();
		cellRenderData2.setCellText(new TextRenderData("000000","使用率"));
		listCellRenderDatas.add(cellRenderData2);
		CellRenderData cellRenderData3 = new CellRenderData();
		cellRenderData3.setCellText(new TextRenderData("000000","使用年限"));
		listCellRenderDatas.add(cellRenderData3);
		RowRenderData headerData = new RowRenderData(listCellRenderDatas);
		headerData.setRowStyle(tStyle);		
		headerData.setCells(listCellRenderDatas);
		
		List<RowRenderData> listRowList = new ArrayList<RowRenderData>();
		
		//将数据存储为了后边生成图样式
		List<String> devname = new ArrayList<String>();
		List<Double> useRate = new ArrayList<Double>();
		List<Integer> useYear = new ArrayList<Integer>();
		
		for(int i = 0; i < 5; i++){
			
			//生成一行数据
			listRowList.add(RowRenderData.build("电灯_"+i,String.valueOf(Math.random()*100)+"%",String.valueOf(i+1)));
			
			//存入list,为了生成图表
			devname.add("电灯_"+i);
			useRate.add(Math.random()*100);
			useYear.add(i+1);
		}
		data.put("table",new MiniTableRenderData(headerData,listRowList));
		
		/* 测试图表的插入-------------------------------------*/
		//柱状图生成
		ChartMultiSeriesRenderData bar = new ChartMultiSeriesRenderData();
		bar.setChartTitle("barCharts");
		//参数为数组
		bar.setCategories(devname.toArray(new String[devname.size()]));
		List<SeriesRenderData> seriesRenderDatas = new ArrayList<SeriesRenderData>();
		seriesRenderDatas.add(new SeriesRenderData("使用率",useRate.toArray(new Double[useRate.size()])));
		seriesRenderDatas.add(new SeriesRenderData("使用年限",useYear.toArray(new Integer[useYear.size()])));
		bar.setSeriesDatas(seriesRenderDatas);
		data.put("barCharts",bar);
		
		//折线图生成
		ChartMultiSeriesRenderData line = new ChartMultiSeriesRenderData();
		line.setChartTitle("lineCharts");
		//参数为数组
		line.setCategories(devname.toArray(new String[devname.size()]));
		List<SeriesRenderData> seriesRenderDatas1 = new ArrayList<SeriesRenderData>();
		seriesRenderDatas1.add(new SeriesRenderData("使用率",useRate.toArray(new Double[useRate.size()])));
		seriesRenderDatas1.add(new SeriesRenderData("使用年限",useYear.toArray(new Integer[useYear.size()])));
		line.setSeriesDatas(seriesRenderDatas1);
		data.put("lineCharts",line);
		
		//柱状图、折线图共存
		ChartMultiSeriesRenderData barLine = new ChartMultiSeriesRenderData();
		barLine.setChartTitle("barLineCharts");
		barLine.setCategories(devname.toArray(new String[devname.size()]));
		
		List<SeriesRenderData> seriesRenderDatas2 = new ArrayList<SeriesRenderData>();
		SeriesRenderData seriesRenderData1 = new SeriesRenderData();
		seriesRenderData1.setName("使用率bar");
		seriesRenderData1.setValues(useRate.toArray(new Double[useRate.size()]));
		seriesRenderData1.setComboType(SeriesRenderData.ComboType.BAR);
		seriesRenderDatas2.add(seriesRenderData1);
		
		SeriesRenderData seriesRenderData2 = new SeriesRenderData();
		seriesRenderData2.setName("使用年限line");
		seriesRenderData2.setValues(useYear.toArray(new Integer[useYear.size()]));
		seriesRenderData2.setComboType(SeriesRenderData.ComboType.LINE);
		seriesRenderDatas2.add(seriesRenderData2);
		
		SeriesRenderData seriesRenderData3 = new SeriesRenderData();
		seriesRenderData3.setName("使用率line");
		seriesRenderData3.setValues(useRate.toArray(new Double[useRate.size()]));
		seriesRenderData3.setComboType(SeriesRenderData.ComboType.LINE);
		seriesRenderDatas2.add(seriesRenderData3);
		
		SeriesRenderData seriesRenderData4 = new SeriesRenderData();
		seriesRenderData4.setName("使用年限bar");
		seriesRenderData4.setValues(useYear.toArray(new Integer[useYear.size()]));
		seriesRenderData4.setComboType(SeriesRenderData.ComboType.BAR);
		seriesRenderDatas2.add(seriesRenderData4);
		
		barLine.setSeriesDatas(seriesRenderDatas2);
		data.put("barLineCharts",barLine);
		
		//饼状图
		ChartSingleSeriesRenderData pie = new ChartSingleSeriesRenderData();
		pie.setChartTitle("饼状图");
		pie.setCategories(devname.toArray(new String[devname.size()]));
		pie.setSeriesData(new SeriesRenderData("电灯数量",new Integer[]{120,25,89,65,49}));
		data.put("pie", pie);

4)写入数据导出

		/*将输入写入模板中------------------------------------------*/
		try {
			//将map数据放入模板
			template.render(data);
			//模板数据写入
			template.write(out);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		out.flush();
		out.close();
		template.close();

 

只写了用到的变量,还可以导入图片,可以参考官方文档。参考链接:http://deepoove.com/poi-tl/

### 使用 poi-tl 创建 Word 文档导出模板 poi-tl 是一个基于 Apache POIJava 类库,专门设计用于简化 Word 模板处理过程。该工具允许开发者利用现有的 Word 文件作为模板,在其中嵌入动态数据以生成最终文档[^1]。 #### 准备工作 在开始之前,确保开发环境中已经安装了必要的组件,包括但不限于 JDK 11 和 Office Word 2019 或更高版本。此外,还需引入 poi-tl 库至项目依赖项中以便后续操作能够顺利执行[^2]。 #### 定义模板结构 创建一个新的 .docx 文件作为基础模板。此文件应包含所有静态文本以及占位符标记,这些标记将在运行时被实际的数据替换掉。对于复杂的内容如表格、图片或多选框等,则需遵循特定语法格式设置相应的标签位置[^3]。 例如,要插入一张图片可采用如下方式: ```xml <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"> <!-- 图片路径 --> </pic:pic> ``` 而对于表格来说,可以通过定义特殊的 XML 结构来支持行的动态增加: ```xml <w:tbl> <w:tr> <!-- 表头 --> </w:tr> ${tableRows} </w:tbl> ``` 这里 `${tableRows}` 就是用来表示将由程序逻辑填充的具体行内容[^4]。 #### 编写代码实现自动化流程 下面给出一段简单的 Java 示例代码片段展示如何加载上述准备好的模板并完成数据注入的过程: ```java import org.apache.poi.xwpf.usermodel.XWPFDocument; import cn.afterturn.easypoi.word.WordExportUtil; public class PoiTlExample { public static void main(String[] args) throws Exception { String templatePath = "path/to/template.docx"; Map<String, Object> dataMap = new HashMap<>(); // 填充dataMap... XWPFDocument doc = WordExportUtil.exportWord(templatePath, dataMap); FileOutputStream fos = new FileOutputStream("output/generated_document.docx"); doc.write(fos); fos.close(); doc.close(); } } ``` 这段代码展示了基本的工作流:指定模板文件的位置,准备好待填入的数据映射表 `dataMap` ,调用 `WordExportUtil.exportWord()` 方法进行渲染最后保存结果到新的文件里去。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值