将数据库内容导入WORD模板中相应位置的小程序
欢迎大家加入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上边的需要花费积分,所以我等新手就地取材就好!
这是我第一次写关于工作上的成果,还是希望大家多多支持,非常感谢。业界大神可与在下互相关注,提携后辈温故知新!