上一次我们利用POI技术完成了出货表的取值、构建以及生产excel文件。下面我们继续利用POI技术来修饰我们之前构造的excel,然后将修饰完的excel能让用户下载。
回顾一下之前用代码生成的excel
我们的表格并不是很好看,而且大部分表格的长度不足以存储数据,我们要对这个表进行完整的修改。
记不记得我们之前的出货表样板:
我们现在没有标题,所以要给它加一个标题,这个标题是需要单元格合并的,所以我们在这里设置它
完整代码:
但是样式还是不好看,并且标题还不是居中的,我们再修改一下标题:
其中bigTitle方法
最后测试一下打印出来的结果:
符合我们的需求,我们接下来修饰一下我们下面的所有数据表格,设置字体与表格宽度等属性,修改后的完整代码为:
修饰后效果
为了方便之后的打印,我们还要思考以下问题:
1.添加页脚,因为要打印多张,以防打印出错。
2.要将表调整成横向,因为纵向打印会超出纸张的宽度。
3.每张都要添加标题栏,不然会弄混
4.内容样式稍有不同,就需要创建不同的格式的样式,写很多样式应用的语句。
这些问题我们之后再来解决,我们先给系统页面添加一个连接,好下载打印完成之后的文档:
我们将之前的生产文件代码:
修改为:
其中DownloadUtil类是我们的工具类,此类的详细代码为:
然后我们再重启服务器,选择日期点击打印之后,发现弹出了下载框:
回顾一下之前用代码生成的excel
我们的表格并不是很好看,而且大部分表格的长度不足以存储数据,我们要对这个表进行完整的修改。
记不记得我们之前的出货表样板:
我们现在没有标题,所以要给它加一个标题,这个标题是需要单元格合并的,所以我们在这里设置它
- //大标题,合并单元格
- sheet.addMergedRegion(new CellRangeAddress(0,0,1,9));//开始行,结束行,开列,结束列
- //合并单元格的内容是写在合并前第一个单元格中
- nRow=sheet.createRow(rowNo++);
- nCell=nRow.createCell(1);
- nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-","年")+"月份出货表");//yyyy-MM
完整代码:
- //打印
- @RequestMapping("/cargo/outproduct/print.action")
- public void print(String inputDate) throws IOException{ //inputDate格式:yyyy-MM
- List<OutProductVO> dataList=outProductService.find(inputDate);
- /*System.out.println(dataList.size());
- System.out.println(inputDate);*/
- Workbook wb=new HSSFWorkbook();
- Sheet sheet=wb.createSheet();
- Row nRow=null;
- Cell nCell=null;
- int rowNo=0; //行号
- int cellNo=1;//列号
- //大标题,合并单元格
- sheet.addMergedRegion(new CellRangeAddress(0,0,1,9));//开会行,结束行,开始列,结束列
- //合并单元格的内容是写在合并前第一个单元格中
- nRow=sheet.createRow(rowNo++);
- nCell=nRow.createCell(1);
- nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-","年")+"月份出货表");//yyyy-MM
- //配置标题行
- String [] title=new String[]{"客户","订单号","货号","数量","工厂","附件","工厂交期","船期","贸易条款"};
- nRow=sheet.createRow(rowNo++);
- for (int i = 0; i < title.length; i++) {
- nCell=nRow.createCell(i+1);
- nCell.setCellValue(title[i]);
- }
- //处理数据
- for (int i = 0; i < dataList.size(); i++) {
- OutProductVO op=dataList.get(i);
- nRow=sheet.createRow(rowNo++);
- cellNo=1;//列号初始化
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCustomName());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getcontractNo());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getProductNo());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCnumber());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getFactoryName());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getExts());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getDelivery_preriod());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getShip_time());
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getTradeTerms());
- }
- OutputStream os=new FileOutputStream(new File("F:\\outproduct.xls"));
- wb.write(os);
- os.close();
- }
然后打印出来的效果是:
但是样式还是不好看,并且标题还不是居中的,我们再修改一下标题:
- //声明样式对象和字体对象
- CellStyle nStyle=wb.createCellStyle();
- Font nFont=wb.createFont();
- //大标题,合并单元格
- sheet.addMergedRegion(new CellRangeAddress(0,0,1,9));//开会行,结束行,开始列,结束列
- //合并单元格的内容是写在合并前第一个单元格中
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(36);//行高
- nCell=nRow.createCell(1);
- nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-","年")+"月份出货表");//yyyy-MM
- nCell.setCellStyle(this.bigTitle(wb, nStyle, nFont));
其中bigTitle方法
- //大标题样式
- public CellStyle bigTitle(Workbook wb,CellStyle nStyle,Font nFont){
- nFont.setFontName("宋体");
- nFont.setFontHeightInPoints((short)16);
- //设置字体加粗
- nFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
- //横向居中
- nStyle.setAlignment(CellStyle.ALIGN_CENTER);
- //纵向居中
- nStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
- nStyle.setFont(nFont);
- return nStyle;
- }
最后测试一下打印出来的结果:
符合我们的需求,我们接下来修饰一下我们下面的所有数据表格,设置字体与表格宽度等属性,修改后的完整代码为:
- //打印
- @RequestMapping("/cargo/outproduct/print.action")
- public void print(String inputDate) throws IOException{ //inputDate格式:yyyy-MM
- List<OutProductVO> dataList=outProductService.find(inputDate);
- /*System.out.println(dataList.size());
- System.out.println(inputDate);*/
- Workbook wb=new HSSFWorkbook();
- Sheet sheet=wb.createSheet();
- Row nRow=null;
- Cell nCell=null;
- int rowNo=0; //行号
- int cellNo=1;//列号
- //声明样式对象和字体对象
- CellStyle nStyle=wb.createCellStyle();
- Font nFont=wb.createFont();
- //设置表格宽度
- sheet.setColumnWidth(0,1*300);//列宽
- sheet.setColumnWidth(1,26*300);//列宽
- sheet.setColumnWidth(2,12*300);//列宽
- sheet.setColumnWidth(3,29*300);//列宽
- sheet.setColumnWidth(4,10*300);//列宽
- sheet.setColumnWidth(5,12*300);//列宽
- sheet.setColumnWidth(6,8*300);//列宽
- sheet.setColumnWidth(7,10*300);//列宽
- sheet.setColumnWidth(8,10*300);//列宽
- sheet.setColumnWidth(9,8*300);//列宽
- //大标题,合并单元格
- sheet.addMergedRegion(new CellRangeAddress(0,0,1,9));//开会行,结束行,开始列,结束列
- //合并单元格的内容是写在合并前第一个单元格中
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(36);//行高
- nCell=nRow.createCell(1);
- nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-","年")+"月份出货表");//yyyy-MM
- nCell.setCellStyle(this.bigTitle(wb, nStyle, nFont));
- //配置标题行
- String [] title=new String[]{"客户","订单号","货号","数量","工厂","附件","工厂交期","船期","贸易条款"};
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(26.25f);//标题的高
- nStyle=wb.createCellStyle();//重新初始化样式
- nFont=wb.createFont();//重新初始化字体
- for (int i = 0; i < title.length; i++) {
- nCell=nRow.createCell(i+1);
- nCell.setCellValue(title[i]);
- nCell.setCellStyle(this.Title(wb, nStyle, nFont));
- }
- nStyle=wb.createCellStyle();//重新初始化样式
- nFont=wb.createFont();//重新初始化字体
- //处理数据
- for (int i = 0; i < dataList.size(); i++) {
- OutProductVO op=dataList.get(i);
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(24);//数据框的高
- cellNo=1;//列号初始化
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCustomName());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getcontractNo());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getProductNo());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCnumber());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getFactoryName());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getExts());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getDelivery_preriod());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getShip_time());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getTradeTerms());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- }
- OutputStream os=new FileOutputStream(new File("F:\\outproduct.xls"));
- wb.write(os);
- os.close();
- }
- //大标题样式
- public CellStyle bigTitle(Workbook wb,CellStyle nStyle,Font nFont){
- nFont.setFontName("宋体");
- nFont.setFontHeightInPoints((short)16);
- //设置字体加粗
- nFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
- //横向居中
- nStyle.setAlignment(CellStyle.ALIGN_CENTER);
- //纵向居中
- nStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
- nStyle.setFont(nFont);
- return nStyle;
- }
- //标题样式
- public CellStyle Title(Workbook wb,CellStyle nStyle,Font nFont){
- nFont.setFontName("黑体");
- nFont.setFontHeightInPoints((short)12);
- //设置字体加粗
- nFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
- //横向居中
- nStyle.setAlignment(CellStyle.ALIGN_CENTER);
- //纵向居中
- nStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
- //表格线(上下左右的细线)
- nStyle.setBorderTop(CellStyle.BORDER_THIN);
- nStyle.setBorderLeft(CellStyle.BORDER_THIN);
- nStyle.setBorderRight(CellStyle.BORDER_THIN);
- nStyle.setBorderBottom(CellStyle.BORDER_THIN);
- nStyle.setFont(nFont);
- return nStyle;
- }
- //文字样式
- public CellStyle Text(Workbook wb,CellStyle nStyle,Font nFont){
- nFont.setFontName("Times New Roman");
- nFont.setFontHeightInPoints((short)10);
- //横向居中
- nStyle.setAlignment(CellStyle.ALIGN_CENTER);
- //纵向居中
- nStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
- //表格线(上下左右的细线)
- nStyle.setBorderTop(CellStyle.BORDER_THIN);
- nStyle.setBorderLeft(CellStyle.BORDER_THIN);
- nStyle.setBorderRight(CellStyle.BORDER_THIN);
- nStyle.setBorderBottom(CellStyle.BORDER_THIN);
- nStyle.setFont(nFont);
- return nStyle;
- }
修饰后效果
为了方便之后的打印,我们还要思考以下问题:
1.添加页脚,因为要打印多张,以防打印出错。
2.要将表调整成横向,因为纵向打印会超出纸张的宽度。
3.每张都要添加标题栏,不然会弄混
4.内容样式稍有不同,就需要创建不同的格式的样式,写很多样式应用的语句。
这些问题我们之后再来解决,我们先给系统页面添加一个连接,好下载打印完成之后的文档:
我们将之前的生产文件代码:
- OutputStream os=new FileOutputStream(new File("F:\\outproduct.xls"));
- wb.write(os);
- os.flush();
- os.close();
修改为:
- //下载(使用了我们的工具类)
- DownloadUtil du=new DownloadUtil();
- ByteArrayOutputStream bs=new ByteArrayOutputStream();
- wb.write(bs);
- du.download(bs, response, "出货表.xls");
其中DownloadUtil类是我们的工具类,此类的详细代码为:
- package cn.hpu.jk.Util;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- public class DownloadUtil {
- /**
- * @param filePath 要下载的文件路径
- * @param returnName 返回的文件名
- * @param response HttpServletResponse
- * @param delFlag 是否删除文件
- */
- protected void download(String filePath,String returnName,HttpServletResponse response,boolean delFlag){
- this.prototypeDownload(new File(filePath), returnName, response, delFlag);
- }
- /**
- * @param file 要下载的文件
- * @param returnName 返回的文件名
- * @param response HttpServletResponse
- * @param delFlag 是否删除文件
- */
- protected void download(File file,String returnName,HttpServletResponse response,boolean delFlag){
- this.prototypeDownload(file, returnName, response, delFlag);
- }
- /**
- * @param file 要下载的文件
- * @param returnName 返回的文件名
- * @param response HttpServletResponse
- * @param delFlag 是否删除文件
- */
- public void prototypeDownload(File file,String returnName,HttpServletResponse response,boolean delFlag){
- // 下载文件
- FileInputStream inputStream = null;
- ServletOutputStream outputStream = null;
- try {
- if(!file.exists()) return;
- response.reset();
- //设置响应类型 PDF文件为"application/pdf",WORD文件为:"application/msword", EXCEL文件为:"application/vnd.ms-excel"。
- response.setContentType("application/octet-stream;charset=utf-8");
- //设置响应的文件名称,并转换成中文编码
- //returnName = URLEncoder.encode(returnName,"UTF-8");
- returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1")); //保存的文件名,必须和页面编码一致,否则乱码
- //attachment作为附件下载;inline客户端机器有安装匹配程序,则直接打开;注意改变配置,清除缓存,否则可能不能看到效果
- response.addHeader("Content-Disposition", "attachment;filename="+returnName);
- //将文件读入响应流
- inputStream = new FileInputStream(file);
- outputStream = response.getOutputStream();
- int length = 1024;
- int readLength=0;
- byte buf[] = new byte[1024];
- readLength = inputStream.read(buf, 0, length);
- while (readLength != -1) {
- outputStream.write(buf, 0, readLength);
- readLength = inputStream.read(buf, 0, length);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- outputStream.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- outputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- inputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- //删除原文件
- if(delFlag) {
- file.delete();
- }
- }
- }
- /**
- * by tony 2013-10-17
- * @param byteArrayOutputStream 将文件内容写入ByteArrayOutputStream
- * @param response HttpServletResponse 写入response
- * @param returnName 返回的文件名
- */
- public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException{
- response.setContentType("application/octet-stream;charset=utf-8");
- returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1")); //保存的文件名,必须和页面编码一致,否则乱码
- response.addHeader("Content-Disposition", "attachment;filename=" + returnName);
- response.setContentLength(byteArrayOutputStream.size());
- ServletOutputStream outputstream = response.getOutputStream(); //取得输出流
- byteArrayOutputStream.writeTo(outputstream); //写到输出流
- byteArrayOutputStream.close(); //关闭
- outputstream.flush(); //刷数据
- }
- }
然后我们再重启服务器,选择日期点击打印之后,发现弹出了下载框:
之后点击保存之后,发现我们已经将文件下载到桌面上了,打开之后发现内容完全正确:
好,至此我们的出货表的构造和打印完成!下一次我们将用另外一种更好方法来设计我们的出货表。