spring整合导出excle和PDF

导出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);
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值