将数据库内容导入WORD模板中相应位置的小程序


欢迎大家加入CSDN开发云
CSDN开发云
最近刚刚入职了一家新公司,上班第一天技术经理就给分配了一个小任务:既不是加入一个团队,也不是提前熟悉即将开始的新项目,而是让我写一个小程序。
这个小程序听起来很简单,就是将数据库中部分字段的内容填写到WORD模板中,而需要填写的内容就是写入乙方的信息;

其实这个小程序主要考验JAVA的基础知识(当然这也是程序做完之后才有了这个感觉),比如说数据库连接工具,集合等等,最重要的是如何将获取到的内容添加到相应的位置。一开始接到这项任务我以为会在很短的时间搞定它,因为经理没有说什么时候交项目,只能是越快越好了。在准备阶段我接收了同事发给我的sql数据,启用了公司的数据库,同时给电脑安装了软件(因为是重装的系统),我配置的是JDK1.8,eclipse用的官网最新版(地址: https://www.eclipse.org/downloads/,版本Eclipse IDE 201809
),选择使用哪种方式来制作这个小程序。最开始我是想做的完美一些,成为一个真正的程序,以后随时都能用,所以提前考虑了一下到底用哪种方式来写,当时心里有好多备选答案,灵感有很多,确实很纠结。可是当下手开始敲代码的时候,却没了底,验证了好多方法都行不通,觉得有些失望了,经理看我很纠结,就说基本能用就行,不需要太高大上。所以,我就用了最简单的办法来解决这个问题,如下所示:

1.创建DBUtil工具类连接数据库:

/**
 * 数据库连接工具
 * @author Administrator
 *
 */
public class DBConn {
//	路径
		private String db;
//		账户
		private String username;
//		密码
		private String password;
		
		public DBConn (String db,String username,String  password) {
				this.db=db;
				this.username=username;
				this.password=password;
		}

		public String getDb() {
			return db;
		}

		public void setDb(String db) {
			this.db = db;
		}

		public String getUsername() {
			return username;
		}

		public void setUsername(String username) {
			this.username = username;
		}

		public String getPassword() {
			return password;
		}

		public void setPassword(String password) {
			this.password = password;
		}
		
//		获取数据库连接
		public Connection getConnection() {
				Connection conn=null;
				try {
//					加载数据库驱动
					Class.forName("com.mysql.jdbc.Driver");
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					System.out.println("数据库驱动异常");
					return null;
				}
				String url="jdbc:mysql:数据库路径"+this.db+"?&useUnicode=true"
						+"&characterEncoding=UTF-8&useSSL=false";
				try {
//					连接mysal数据库
					conn=DriverManager.getConnection(url, this.username, this.password);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					System.out.println("连接数据库异常");
					return null;
				}
				System.out.println("连接数据库成功");
				return conn;
		}
//		关闭数据库
		public void closeConn(Connection conn) {
			if (conn!=null) {
				try {
					conn.close();
					System.out.println("关闭数据库连接");
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		public List<Map<String, String>>query(String sql,Object[]obj){
			Connection conn=getConnection();
			PreparedStatement ps=null;
			ResultSet rs=null;
			List<Map<String,String>>list=new ArrayList<>();
			try {
				ps=conn.prepareStatement(sql);
				if(obj!=null) {
					for(int i=0;i<obj.length;i++) {
						ps.setObject(i+1, obj[i]);
					}
				}
				rs=ps.executeQuery();
				ResultSetMetaData rsmd=rs.getMetaData();
				while(rs.next()) {
					Map<String, String>map=new HashMap<>();
					for(int i = 0;i<rsmd.getColumnCount();i++) {
						String columName=rsmd.getColumnName(i+1);
						String columValue=rs.getString(i+1);
						map.put(columName, columValue);
					}
					list.add(map);
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}finally {
				isClose(ps,conn,rs);
			}
			return list;
		}
			private void isClose(PreparedStatement ps, Connection conn, ResultSet rs) {
			try {
				if (ps!=null) {
					ps.close();
				}
				if (conn!=null) {
					conn.close();
				}
				if (rs!=null) {
					rs.close();
				}
			} catch (Exception e) {
			}
		}
			public static void main(String[] args) {
				DBConn dbc=new DBConn("数据库名称", "账户", "密码"");
				Connection conn=dbc.getConnection();
				dbc.closeConn(conn);
			}
}

2.创建DAO层:

主要是将从数据获得的内容赋值到word模板中(.docx格式)

public class UsrDao {
//		取出数据库中的内容
			public List<UsrBean>getAllUsrs(int cust_id){
//				获取数据库连接
				DBConn dbc=new DBConn("数据库名称", "登录名", "密码");
				Connection conn=dbc.getConnection();
//				判断连接
				if(conn==null) {
					System.out.println("数据库连接出错");
					return null;
				}
				String sql="select cust_name,rsrv_str3,juristic,email,cell_phone,company_address,registration_time from company where cust_id=?";
				Object[]obj= {cust_id};
				PreparedStatement pStatement=null;
				ResultSet rs=null;
				List<UsrBean>lists=new ArrayList<>();
				try {
//					预编译处理sql语句
					pStatement=conn.prepareStatement(sql);
					if(obj!=null) {
						for(int i=0;i<obj.length;i++) {
							pStatement.setObject(i+1, obj[i]);
						}
					}
					rs=pStatement.executeQuery();
					ResultSetMetaData rsmd=rs.getMetaData();
					Map<String, String>map=new HashMap<>();
					List<Map<String, String>> maps =new ArrayList<>();
					UsrBean usr=new UsrBean();
					while(rs.next()) {
						
						for(int i=0;i<rsmd.getColumnCount();i++) {
							String columName=rsmd.getColumnName(i+1);
							String columValue=rs.getString(i+1);
							map.put(columName, columValue);
						}
						maps.add(map);
//						赋值
						usr.setCust_name(maps.get(0).get("CUST_NAME"));
						usr.setRsrv_str3(maps.get(0).get("RSRV_STR3"));
						usr.setJuristic(maps.get(0).get("JURISTIC"));
						usr.setEmail(maps.get(0).get("EMAIL"));
						usr.setCell_phone(maps.get(0).get("CELL_PHONE"));
						usr.setCompany_address(maps.get(0).get("COMPANY_ADDRESS"));
						usr.setRegistration_time(maps.get(0).get("REGISTRATION_TIME"));
//					将变量存入数组中
						lists.add(usr);
					}
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println("SQL语句有误,数据库无法查询");
					//return null;
				} finally {
					dbc.closeConn(conn);
				}			
				return lists;
			}
//			内部测试
					public static void main(String[] args) {
						UsrDao usrDao=new UsrDao();
						System.out.println(usrDao.getAllUsrs(6348).get(0).getRegistration_time());
					}		
}

3.查询数据库中的公司数据

public class GetId {
	/**
	 * 找到数据库中所有的id 
	 * 得出的结果是集合
	 * @return
	 */
		public List<Integer> getAllId() {
//			获取数据库连接
			DBConn dbc=new DBConn("数据库名称", "账户", "密码");
			Connection conn=dbc.getConnection();
			List<Integer>lists=new ArrayList<>();
//			判断连接
			if(conn==null) {
				System.out.println("数据库连接出错");
				return null;
			}
//			查询公司名称除了“______”的sql语句
			String sql="需要的SQL语句";
			Map<String, String>map=new HashMap<>();
			List<Map<String, String>> maps =new ArrayList<>();
//			预编译语句
			try {
				PreparedStatement ps=conn.prepareStatement(sql);
				ResultSet rs=ps.executeQuery();
				ResultSetMetaData rsmd=rs.getMetaData();
				UsrBean usr=new UsrBean();
				while(rs.next()) {
					for(int i=0;i<rsmd.getColumnCount();i++) {
						String columName=rsmd.getColumnName(i+1);
						String columValue=rs.getString(i+1);
						map.put(columName, columValue);
					}
					int cid = Integer.parseInt(map.get("大写的字段名"));
//					赋值
					lists.add(cid);
				}
			} catch (SQLException e) {
				e.printStackTrace();
				System.out.println("SQL语句有误,数据库无法查询");
				//return null;
			} finally {
				dbc.closeConn(conn);
			}
			return lists;			
			
		}
		public static void main(String[] args) {
			GetId gd=new GetId();
			for (Integer usr : gd.getAllId()) {
				System.out.println(usr);
			}
		}
}

非常重要的地方

4.文档操作设置

段落的设置,获取文档,操作赋值,完成工作。当然这是网上的大神分享的,很专业很实用。链接写在文章下方,想要具体了解的朋友可以点击查看。

	/**
	 * 替换段落里面的变量
	 * 
	 * @param doc
	 *            要替换的文档
	 * @param params
	 *            参数
	 */
	private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
		Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
		XWPFParagraph para;
		while (iterator.hasNext()) {
			para = iterator.next();
			this.replaceInPara(para, params);
		}
	}
 
	/**
	 * 替换段落里面的变量
	 * 
	 * @param para
	 *            要替换的段落
	 * @param params
	 *            参数
	 */
	private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
		List<XWPFRun> runs;
		Matcher matcher;
		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);
					if(runText.equals("null")){
						runText="";
					}
					para.insertNewRun(i).setText(runText);
				}
			}
		}
	}
	/**
	 * 替换表格里面的变量
	 * 
	 * @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) {
					
					String cellTextString = cell.getText();
                    for (Entry<String, Object> e : params.entrySet()) {
                        if (cellTextString.contains("${"+e.getKey()+"}"))
                            cellTextString = cellTextString.replace("${"+e.getKey()+"}", e.getValue().toString());
                    }
                    cell.removeParagraph(0);
                    if(cellTextString.contains("${") && cellTextString.contains("}")){
                    	cellTextString = "";
                    }
                    cell.setText(cellTextString);
//                    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();
			}
		}
	}
 
	/**
	 * 输出CoreProperties信息
	 * 
	 * @param coreProps
	 */
	private void printCoreProperties(CoreProperties coreProps) {
//		System.out.println(coreProps.getCategory()); // 分类
//		System.out.println(coreProps.getCreator()); // 创建者
//		System.out.println(coreProps.getCreated()); // 创建时间
//		System.out.println(coreProps.getTitle()); // 标题
	}
	
	/**
	 * word占位用${object}有缺陷不能填充图片
	 * @param filePath
	 * @param params
	 * @throws Exception
	 */
	public static String templateWrite(String filePath, Map<String, Object> params,String outFilePath)throws Exception{
		InputStream is = new FileInputStream(filePath);
		WriteWordUtil writeWordUtil = new WriteWordUtil();
		XWPFDocument doc = new XWPFDocument(is);
		// 替换段落里面的变量
		writeWordUtil.replaceInPara(doc, params);
		// 替换表格里面的变量
		writeWordUtil.replaceInTable(doc, params);
		OutputStream os = new FileOutputStream(outFilePath);
		doc.write(os);
		writeWordUtil.close(os);
		writeWordUtil.close(is);
		os.flush();
		os.close();
		return "";
	}
	 /**
     * 使用方法将内容填充
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
//		从数据库获取数据
    	GetId getId=new GetId();
    	List<Integer> allId = getId.getAllId();
    	for (Integer int1 : allId) {
    		List<UsrBean> usrs=new UsrDao().getAllUsrs(int1);
    		if(usrs==null) {
    			System.out.println("数据库获取失败");
    			return;
    		}
//    		将数据具体信息展示
    	String name= usrs.get(0).getCust_name();
    	String num=usrs.get(0).getRsrv_str3();
    	String user=usrs.get(0).getJuristic();
    	String email=usrs.get(0).getEmail();
    	String phone=usrs.get(0).getCell_phone();
//    	注册时间
    	String time=usrs.get(0).getRegistration_time();
    	String address=usrs.get(0).getCompany_address();
    	Map<String, Object> params = new HashMap<String, Object>();
    	
}

上述模板生成器转载至: https://blog.csdn.net/chen497147884/article/details/79678513
需要生成的WORD模板里需要修改的内容;

我所使用的是最新版本的WPS2019挺好用的,很方便。

更重要的差点忘了,那就是写程序必备的jar包,强烈推荐的是POI3.1.7版本,
别用最新的版本,实测4.0.1的没法用。下载地址: http://www.33lc.com/soft/75246.html。因为CSDN上边的需要花费积分,所以我等新手就地取材就好!
这是我第一次写关于工作上的成果,还是希望大家多多支持,非常感谢。业界大神可与在下互相关注,提携后辈温故知新!

欢迎大家加入CSDN开发云
CSDN开发云

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值