工作中涉及了制作电子表格,经过多次尝试,感觉使用模版表实现表格输出最为合适。采用现在流行的JAVA WEB方式实现,开发自己的电子表格系统。开发工具ECLIPSE3.2;JAVA JDK5.0 ;POI包poi-3.0-alpha3-20070224.jar(可以到http://www.apache.org/dyn/closer.cgi/jakarta/poi/下载);应用服务器选择 TOMCAT5.0.28 下面就介绍一下我开发中涉及的技术已经实现方案:
eclipse 工程包选择 WEB PROJECT,开发JAVA的ORACLE 连接,操作功能块,主要是实现查询返回结果的功能,后台数据库选择 ORACLE,在建设JAVA连接数据库类是要考虑使用共享池方式实现。后台数据库建立,原始数据表,用于存放业务逻辑数据,最重要的是数据模型设计时应充分考虑灵活使用表格字段。即表同一字段的使用仅仅跟据字段属性有关,而和业务逻辑无关,就是说不能将每个字段设定为仅为一类业务逻辑属性而设计。这样做的目的就是为了使我们在设计模版表的时候只要对应数据库表的字段属性设定取值条件就可完成单元格数据的填充。本人在做模版表设计中利用的是EXCL表的单元格批注功能,在单元格批注中写入该单元格取原始数据表数据的条件。当然不是查询语句了。仅仅是分割符号以及数字串如:“@81,@85@@@@801@0@@/2”;做好模版后,就可以通过编写 串分析功能模块,实现解析串为查询语句了。当然你看到了,在逻辑描述串中还包括四则运算符号,这都是必不可少的功能。接下来我贴出读取模版表的源代码块:
public static void initExcl(String intfilename,String outfilename) throws IOException
{
FileInputStream _fileSystem; //输入文件流对象
POIFSFileSystem fs; //文件系统对象
if ((intfilename == null) || (intfilename.equals("")))
throw new NullPointerException ("输入文件名错误!");
//根据输入路径文件名,建立模版表实例
_fileSystem = new FileInputStream(intfilename);
fs = new POIFSFileSystem(_fileSystem);
_workbook = new HSSFWorkbook (fs);
//建立输出表实例
_workbook_out = new HSSFWorkbook();
fileOut = new FileOutputStream(outfilename);
}
---随后读取模版表循环查看模版表单元格格式等信息。复制过来。
public static int exclDeal(String starttime,String endtime,String groupbycol) throws IOException
{
//用模版表包括的sheet数做循环
for (int numSheets = 0; numSheets < _workbook.getNumberOfSheets(); numSheets++)
{
//建立模版表sheet实例
HSSFSheet sheet = _workbook.getSheetAt(numSheets);
//add haor 20070209
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, _workbook);
//end add
//取模版表sheet名
String sheetname=_workbook.getSheetName(numSheets);
//分解sheet类型sheet名的最后一个字符,确定输出表类型,A交叉表,B平行表,C复合表
f_flag=sheetname.substring(sheetname.length()-1);
System.out.println(f_flag);
/* if ((f_flag.charAt(0)!='A')&&(f_flag.charAt(0)!='B')&&(f_flag.charAt(0)!='C')){
//如果不是匹配的sheet名执行下一个循环
}*/
//建立同名(去掉最后一个字符)输出sheet实例
HSSFSheet sheet_out = _workbook_out.createSheet();
//处理汉字sheet名 使用 HSSFWorkbook.ENCODING_UTF_16
_workbook_out.setSheetName(numSheets, _workbook.getSheetName(numSheets), HSSFWorkbook.ENCODING_UTF_16);
//要求模版表第一行为标题,不能为空行
//获得当前sheet中行记录数()
int rows =sheet.getPhysicalNumberOfRows();
for (int r = 0; r < rows; r++) //row numbers
{//create instance for row
HSSFRow row = sheet.getRow(r); //current row
HSSFRow row_out =sheet_out.createRow(r);
//处理空行的情况
if (row==null){
continue;
}
//设置单元格所在行 add haor 20070209
evaluator.setCurrentRow(row);
//end add
int cells = row.getPhysicalNumberOfCells(); //column numbers
for (short c = 0; c < cells; c++)
{
//获得当前单元格对象实例
HSSFCell cell =row.getCell(c);
//建立输出单元格对象实例
HSSFCell cell_out=row_out.createCell(c);
//单元格汉字编码转换
cell_out.setEncoding(HSSFCell.ENCODING_UTF_16);
//获得列宽
short colWidth=sheet.getColumnWidth(c);
//设置 单元格列宽
sheet_out.setColumnWidth(c, colWidth);
//获得行高
short rowHeigth = row.getHeight();
//设置 行高
row_out.setHeight(rowHeigth);
//使用源模版表单元格边框格式设定目标表
HSSFCellStyle cellStyle=cell.getCellStyle();
//单元格属性设置
HSSFCellStyle cellStyle_out = _workbook_out.createCellStyle();
//判断是否合并单元格
//System.out.println(sheet.getNumMergedRegions());
for (int i = 0; i < sheet.getNumMergedRegions(); i++){
Region region = sheet.getMergedRegionAt(i);
if ((region.getRowFrom() >= r) && (region.getRowTo() <= region.getRowTo())){
int targetRowFrom = region.getRowFrom() ;
int targetRowTo = region.getRowTo() ;
region.setRowFrom(targetRowFrom);
region.setRowTo(targetRowTo);
sheet_out.addMergedRegion(region);
}
}
//---------------------------------------------------------------------
// 设置标题的字体
//HSSFFont font_src = _workbook.createFont();
//font_src=_workbook.getFontAt(c);
HSSFFont font_out = _workbook_out.createFont();
//字体大小
//short h =font_src.getFontHeightInPoints();
font_out.setFontHeightInPoints((short)10);
//font_out.setFontHeightInPoints(h);
//String fn=font_src.getFontName();
//font_out.setFontName(fn);
font_out.setFontName("宋体");
cellStyle_out.setFont(font_out);
//---------------------------------------------------------------------
//使用模版边框属性设置输出单元格属性
cellStyle_out.setBorderTop(cellStyle.getBorderTop());
cellStyle_out.setBorderBottom(cellStyle.getBorderBottom());
cellStyle_out.setBorderLeft(cellStyle.getBorderLeft());
cellStyle_out.setBorderRight(cellStyle.getBorderRight());
//设定单元格边框线条颜色
cellStyle_out.setTopBorderColor(cellStyle.getTopBorderColor());
//cellStyle_out.setTopBorderColor(HSSFColor.BLACK.index);
cellStyle_out.setBottomBorderColor(cellStyle.getBottomBorderColor());
cellStyle_out.setLeftBorderColor(cellStyle.getLeftBorderColor());
cellStyle_out.setRightBorderColor(cellStyle.getRightBorderColor());
cell_out.setCellStyle(cellStyle_out);
// add haor 20070209
HSSFFormulaEvaluator.CellValue cellValue = evaluator.evaluate(cell);
--接下来就是判断单元格了看是数值,串,还是公式了,只要是串就继续判串中的批注是否有@,如果有那么就分析批注中的串,(这个分析功能模块我就不贴了◎``◎,自己动脑筋吧)。接着转换为查询语句,执行查询返回结果。好得到结果后,(记得要做串转换为数值的处理。);
//放置数值型数据(字符串表达式计算结果返回Double型数)
if (isExpression(unionStr)){
Double getvaluesql=new CalStr(unionStr).getResult();
cell_out.setCellValue(getvaluesql);
}else{
Double getvaluesql=Double.parseDouble(unionStr);
cell_out.setCellValue(getvaluesql);
}
--依次循环获得单元格描述,或复制或取值放入,最后关闭输出实例。生成表格。
最后一步就是建立 JSP文件来调用这个应用类了。应该很容易做到了。在调入界面中要涉及,文件下载的技术,以及管理功能模块涉及模版文件上传的技术。网络上文章较多。请记得完成生成表格后要是用户可以从界面将生成的输出表格下载到本地。上述功能完成后整合系统界面完成项目开发。如果用户有新的表格,只要通过管理界面上传模版表,在ORACLE 使用过程、语句等将业务数据时时或定期导入到原始数据表,那么就可以实现随时输出表格了。