上一次我们利用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(); //刷数据
}
}
然后我们再重启服务器,选择日期点击打印之后,发现弹出了下载框:
之后点击保存之后,发现我们已经将文件下载到桌面上了,打开之后发现内容完全正确:
好,至此我们的出货表的构造和打印完成!下一次我们将用另外一种更好方法来设计我们的出货表。
转载请注明出处:http://blog.csdn.net/acmman/article/details/48729217