导出excle表格
- 添加依赖
使用apache的开源框架POI<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency>
- 编写自定义的excel视图
import com.chenx.domain.District; import org.apache.commons.beanutils.BeanUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.web.servlet.view.document.AbstractXlsView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.URLEncoder; import java.util.List; import java.util.Map; /** * Created by ChenX on 2017/8/13. */ //想要导出excel,需要继承AbstractXlsView(office2007之前的版本依然可以识别) // ,AbstractXlsxView(office2007版之后的版本才能打开),为了满足大部分人,选择第一种继承 public class DistrictExcelView extends AbstractXlsView { //重写方法 @Override protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { //url中传中文必须转成%编码才能识别 String filename = URLEncoder.encode("省市表格.xls","utf-8"); response.setHeader("Content-Disposition","attachment; filename="+filename); HSSFWorkbook book = (HSSFWorkbook) workbook;//对应一个excel文件 HSSFSheet sheet = book.createSheet("省市区汇总");//在webbook中添加一个sheet,对应Excel文件中的sheet HSSFRow row = sheet.createRow(0);//设置表头第0行 String[] colNames = {"省名字","市名字","地区名字"}; for (int i = 0; i < colNames.length ; i++) { HSSFCell cell = row.createCell(i); cell.setCellValue(colNames[i]); } List<District> districts = (List<District>) model.get("districts"); int rowIndex = 1;//第0行是表头,所以设置从第一行开始 String[] propNames = { "city.province.name", "city.name", "name" }; for (District district : districts ) { HSSFRow sheetRow = sheet.createRow(rowIndex); for (int i = 0; i < propNames.length; i++) { HSSFCell cell = sheetRow.createCell(i); //使用反射取值 cell.setCellValue(BeanUtils.getProperty(district,propNames[i])); } rowIndex++; } } }
- 编写控制器
@GetMapping("/exp") public String exportDistricts(ModelMap map) { List<District> districts = distService.listAllDistricts(); map.put("districts", districts); return "distExcel"; }
PDF文档
- 添加依赖
itext的版本最新已经是5.x了,但是要在spring中使用itex只能支持使用2.x的版本<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency>
- 编写自定义的PDF视图
import com.chenx.domain.District; import com.chenx.utils.PDFUtil; import com.lowagie.text.*; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfWriter; import org.apache.commons.beanutils.BeanUtils; import org.springframework.web.servlet.view.document.AbstractPdfView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.URLEncoder; import java.util.List; import java.util.Map; /** * Created by ChenX on 2017/8/13. */ public class DistrictPdfView extends AbstractPdfView { private final String title_content = "省市区详情"; private final String[] table_head = {"省名字","市名字","区名字"}; @Override protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception { String filename = URLEncoder.encode("省市区详情.pdf","utf-8"); response.setHeader("Content-Disposition", "inline; filename=" + filename); document.open(); //标题 Paragraph title = PDFUtil.getParagraph( new Chunk(title_content,new Font(PDFUtil.bfChinese,16,Font.BOLD))); title.setAlignment(Paragraph.ALIGN_CENTER); document.add(title); //表格标题 PdfPTable table = new PdfPTable(table_head.length); table.setSpacingBefore(20); table.setSpacingAfter(30); for (String str: table_head ) { table.addCell(PDFUtil.getParagraph(str)); } String[] propNames = {"city.province.name", "city.name", "name"}; //表格内容 List<District> distList = (List<District>) model.get("districts"); if (null!=distList){ for (District district:distList ) { for (int i = 0; i < propNames.length; i++) { String content = BeanUtils.getProperty(district, propNames[i]); table.addCell(PDFUtil.getParagraph(content)); } } } document.add(table); document.close(); } }
因为itex默认是不支持中文字体的,所以必须给它添加中文字体,用了一个PDFUtil工具类封装了字体,样式等功能
- PDFUtil工具类
import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.BaseFont; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; public class PDFUtil { // 对参数的封装形式比如{name} public static final String BEGIN = "{"; public static final String END = "}"; // 换行形式{#} public static final String NEW_LINE = "#"; // 默认的行间距、首行距离等,自己添加 public static final float DEFAULT_LEADING = 20; public static final float DEFAULT_LINE_INDENT = 30; // 基本字体和样式 public static BaseFont bfChinese; public static Font fontChinese; public static Font UNDER_LINE = null; static{ try { // SIMKAI.TTF 默认系统语言,这里没使用第三方语言包 //bfChinese = BaseFont.createFont(PDFTest.class.getResource("/content/")+"SIMKAI.TTF",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); bfChinese = BaseFont.createFont("c:/Windows/Fonts/STXINWEI.TTF",BaseFont.IDENTITY_H,true); fontChinese = new Font(bfChinese, 14, Font.NORMAL); UNDER_LINE = new Font(bfChinese, 14,Font.UNDERLINE); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 默认样式 public static Paragraph getParagraph(String context){ return getParagraph(context,fontChinese); } public static Paragraph getParagraph(Chunk chunk){ return new Paragraph(chunk); } // 指定字体样式 public static Paragraph getParagraph(String context,Font font){ return new Paragraph(context,font); } // 获得新行,首行缩进,和行间距 public static Paragraph getNewParagraph(String context,float fixedLeading,float firstLineIndent){ Paragraph p = getParagraph(context); p.setLeading(fixedLeading); p.setFirstLineIndent(firstLineIndent); return p; } public static Paragraph getParagraph(String content , Font font , float fixedLeading , int alignment){ Paragraph p = getParagraph(content); p.setFont(font); p.setLeading(fixedLeading); p.setAlignment(alignment); return p; } // 默认段落样式 public static Paragraph getDefaultParagraph(String context){ Paragraph p = getParagraph(context); // 默认行间距 p.setLeading(DEFAULT_LEADING); // 默认首行空隙 p.setFirstLineIndent(DEFAULT_LINE_INDENT); return p; } // 将参数和字符串内容组合成集合 public static List<Paragraph> createParagraphs(String context , Map<String,Object> map){ int index = 0; List<Paragraph> list = new ArrayList<Paragraph>(); Paragraph p = getDefaultParagraph(null); while((index = context.indexOf(BEGIN)) > -1){ String text = context.substring(0,index); context = context.substring(index, context.length()); index = context.indexOf(END); String param = null; if(index > 0){ param = context.substring(BEGIN.length(),index); } p.add(text); if(!NEW_LINE.equals(param)){ Object value = map.get(param); if(value != null){ p.add(new Chunk(value.toString(),UNDER_LINE)); }else{ p.add(new Chunk("")); } }else{ list.add(p); p = getDefaultParagraph(null); p.setSpacingBefore(0); } context = context.substring(index+END.length(),context.length()); } list.add(p); list.add(getParagraph(context)); return list; } }
- 编写控制器
@GetMapping("/pdf")
public String exportDistrictsToPdf(ModelMap map) {
List<District> districts = distService.listAllDistricts();
map.put("districts", districts);
return "distPdf";
}
- 在PDF中输出图片
在刚刚的自定义视图中添加如下代码document.newPage(); //添加图片 String path = request.getServletContext().getRealPath("/images") + "/" + "mm.jpg"; try (InputStream in = new FileInputStream(path)) { byte[] buffer = new byte[in.available()]; in.read(buffer); // URL url = new URL("https://www.baidu.com/img/bd_logo1.png"); Image image = Image.getInstance(buffer); image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight()); document.add(image); }