itext7實現(xiàn)導(dǎo)出數(shù)據(jù)至pdf壓縮包

1、配置文件中引入itext7依賴jar包
jar包從git上可以獲取不同版本https://github.com/itext/itext7/releases

        <properties>
            <itext.version>7.1.11</itext.version>
        </properties>
        <!-- itext7 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>kernel</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>io</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>layout</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>forms</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>pdfa</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>pdftest</artifactId>
            <version>${itext.version}</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>font-asian</artifactId>
            <version>${itext.version}</version>
        </dependency>

2、代碼部分
導(dǎo)出接口

    @ApiOperation(value = "導(dǎo)出競賣活動列表")
    @RequestMapping(value = "/export/{encrypted}",method = {RequestMethod.GET})
    public void getPdf(@PathVariable String encrypted, HttpServletResponse resp, HttpServletRequest req)
    {
        String decrypted = new String(Base64.getUrlDecoder().decode(encrypted.getBytes()));
        AuctionListRequest listReq = JSON.parseObject(decrypted, AuctionListRequest.class);
        //查詢競賣信息
        List<AuctionVO> auctionVOList = getAuctions(listReq);
        if(CollectionUtils.isEmpty(auctionVOList)){
            throw new SbcRuntimeException();
        }

        try {
            ServletOutputStream os = resp.getOutputStream();
            String destDir = req.getServletContext().getRealPath("/")+ File.separator+"pdfFiles"+File.separator;
            File destDirFile = new File(destDir);
            if(!destDirFile.exists()){
                destDirFile.mkdirs();
            }
            //            PdfFont font = PdfFontFactory.createFont(FONT, PdfEncodings.IDENTITY_H,false);//解決顯示中文字體
            List<File> files = new ArrayList<>();
            auctionVOList.forEach(auctionVO->{
                //文件名:商家名稱-活動名稱-活動開始/結(jié)束時間
                String name = auctionVO.getSupplierName()+"-"+auctionVO.getAuctionName()+"-"+auctionVO.getStartTime().format(DateTimeFormatter.ofPattern(DateUtil.FMT_TIME_2))+"~"+auctionVO.getEndTime().format(DateTimeFormatter.ofPattern(DateUtil.FMT_TIME_2))+".pdf";
                File file = new File(destDir,name);
                PdfWriter writer = null;
                PdfFont font = null;
                try {
                    if(!file.exists()){
                        file.createNewFile();
                    }
                    writer = new PdfWriter(file);
                    font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H",true);
                } catch (Exception e) {
                    log.error("/auction/export/params error: ", e);
                    throw new SbcRuntimeException(SiteResultCode.ERROR_000001);
                }
                PdfDocument pdf = new PdfDocument(writer);
                Document document = new Document(pdf).setFont(font).setFontSize(14);
                //競拍信息
                document.add(new Paragraph("活動詳情-"+auctionVO.getAuctionType().getDesc()).setTextAlignment(TextAlignment.CENTER));
                Table auctionTable = PdfUtil.createTable(2);//創(chuàng)建表格
                Field[] auctionFields = PdfAuctionDto.class.getDeclaredFields();//獲取dto 對象中所有的屬性
                PdfUtil.generateNormalTable(auctionFields,generateAuctionMap(auctionVO),font,auctionTable);
                document.add(auctionTable);
                //拍品信息
                Table auctionGoodsTable = PdfUtil.createTable(12);//創(chuàng)建表格
                Field[] auctionGoodsFields = PdfAuctionGoodsDto.class.getDeclaredFields();//獲取dto 對象中所有的屬性
                List<Map<String,Object>> goodsMaps = new ArrayList<>();
                auctionVO.getAuctionGoodsInfoVOList().forEach(auctionGoodsInfoVO->{
                    goodsMaps.add(generateAuctionGoodsMap(auctionGoodsInfoVO));
                });
                PdfUtil.generateHeadTable(auctionGoodsFields,goodsMaps,font,auctionGoodsTable);
                document.add(auctionGoodsTable);
                //出價記錄
                if(CollectionUtils.isNotEmpty(auctionVO.getAuctionBidVOList())){
                    document.add(new Paragraph(auctionVO.getAuctionType().equals(AuctionType.INCREASE_PRICE)?"出價記錄":"降價記錄").setTextAlignment(TextAlignment.CENTER).setMarginTop(20));
                    Table auctionBidTable = PdfUtil.createTable(7);//創(chuàng)建表格
                    Field[] auctionBidFields = PdfAuctionBidDto.class.getDeclaredFields();//獲取dto 對象中所有的屬性
                    List<Map<String,Object>> bidMaps = new ArrayList<>();
                    auctionVO.getAuctionBidVOList().forEach(auctionBidVO->{
                        bidMaps.add(generateAuctionBidMap(auctionBidVO));
                    });
                    PdfUtil.generateHeadTable(auctionBidFields,bidMaps,font,auctionBidTable);
                    document.add(auctionBidTable);
                }

                document.close();

                files.add(file);
            });

            //如果一個活動直接返回pdf,多個活動則打為壓縮包
//            if(auctionVOList.size() == 1){
//                //商家名稱-活動名稱-活動開始/結(jié)束時間
//                AuctionVO auctionVO = auctionVOList.get(0);
//                filename = auctionVO.getSupplierName()+"-"+auctionVO.getAuctionName()+"-"+auctionVO.getStartTime().format(DateTimeFormatter.ofPattern(DateUtil.FMT_TIME_2))+"/"+auctionVO.getEndTime().format(DateTimeFormatter.ofPattern(DateUtil.FMT_TIME_2))+".pdf";
//                resp.setContentType("application/pdf");
//                resp.getOutputStream();
//            }else{
                //打為zip壓縮包
                String filename = "競賣活動.zip";
                ZipOutputStream zos = new ZipOutputStream(os);
                ZipEntry ze = null;
                for (int i = 0; i < files.size(); i++) {// 將所有需要下載的文件都寫入臨時zip文件
                    BufferedInputStream bis = new BufferedInputStream(
                            new FileInputStream(files.get(i)));
                    ze = new ZipEntry(files.get(i).getName());
                    zos.putNextEntry(ze);
                    int s = -1;
                    while ((s = bis.read()) != -1) {
                        zos.write(s);
                    }
                    bis.close();
                }
                zos.flush();
                zos.close();
                resp.setContentType("application/zip");// 定義輸出類型
//            }

            resp.setHeader("Content-Disposition", "attachment;fileName="+ new String(filename.getBytes("utf-8"),"ISO8859-1"));
            resp.flushBuffer();
        } catch (Exception e) {
            log.error("/auction/export/params error: ", e);
            throw new SbcRuntimeException(SiteResultCode.ERROR_000001);
        } finally {
            exportCount.set(0);
        }
    }

PDF工具類

package com.wanmi.sbc.auction.pdf;

import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.layout.Style;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.DashedBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

public class PdfUtil {

    /**
     * 創(chuàng)建沒有邊框的Cell --設(shè)置字體大小為8,內(nèi)邊距設(shè)置成0,邊框設(shè)置為無邊框
     * @return
     */
    public static Cell getCellNoBorder(){
        return new Cell().setFontSize(10).setPaddings(0,0,0,0).setBorder(Border.NO_BORDER);//setBorder(Border.)
    }

    /**
     * 獲取上邊框為虛線的cell--因為默認情況下,邊框默認是黑色實線邊框,這里要把上邊框設(shè)置成虛線并設(shè)置字體
     * @return
     */
    public static Cell getCellDashedBorder(){
        return new Cell().addStyle(new Style().setBorderTop(new DashedBorder(1))).setBorder(Border.NO_BORDER).setFontSize(10);
    }

    /**
     * 創(chuàng)建兩列的表格并插入圖片
     * @return
     */
    public static Table createTable(int numColumns){
        //創(chuàng)建兩列的表格
        //表格在pdf整個頁面的寬度百分比,這個值越小,整個個pdf表格越小,越靠近左邊(這樣說可能不對,大家可以試下)
        //設(shè)置外邊距
        //設(shè)置圖片在第一行表格中,cell(1,2) 代表這一行,有兩列合并成一列,圖像設(shè)置成自適應(yīng)。這里有一個問題,就是當(dāng)圖像設(shè)置成自適應(yīng)的時候通過new Table(new float[]{4,6})——創(chuàng)建兩列的表格,列長度就是每個數(shù)組長度 創(chuàng)建的表格就會出現(xiàn)表格列長度改變的問題。
        return new Table(numColumns).
                setWidth(UnitValue.createPercentValue(100)).
                setMarginTop(10);
    }

    /**
     * 排序并生成指定樣式的表格
     * @param a
     * @param map
     * @param font
     * @param table
     */
    public static void generateNormalTable(Field[] a, Map<String,Object> map, PdfFont font, Table table){
        for (Field field : a) { //遍歷模板字段
            PdfValue annotation = field.getDeclaredAnnotation(PdfValue.class);//獲取字段屬性上的注釋
            if (0==annotation.typeFile()){
                //如果是沒有邊框的Cell
                table.addCell(getCellNoBorder().add(new Paragraph(annotation.colName()).setFont(font)));
                //字體樣式右對齊,默認是左對齊的
                table.addCell(getCellNoBorder().add(new Paragraph(map.get(field.getName())==null?"-":map.get(field.getName()).toString())).setFont(font));
            }
        }
    }

    /**
     * 有表頭的Table
     * @param a
     * @param maps
     * @param font
     * @param table
     */
    public static void generateHeadTable(Field[] a, List<Map<String,Object>> maps, PdfFont font, Table table){
        //表頭
        for (Field field : a) { //遍歷模板字段
            PdfValue annotation = field.getDeclaredAnnotation(PdfValue.class);//獲取字段屬性上的注釋
            table.addCell(new Paragraph(annotation.colName()).setFont(font).setFontSize(10));
        }
        //內(nèi)容
        maps.forEach(map->{
            for (Field field : a) { //遍歷模板字段
                //字體樣式右對齊,默認是左對齊的
                table.addCell(new Paragraph(map.get(field.getName())==null?"-": map.get(field.getName()).toString())).setFont(font).setFontSize(10);
            }
        });
    }
}

PDF字段實體,這邊只放一個作為示例

package com.wanmi.sbc.auction.pdf;

import lombok.Data;

@Data
public class PdfAuctionDto {
    /**
     * 所屬商家
     */
    @PdfValue(colName = "所屬商家:",typeFile = 0)
    private String supplierName;

    /**
     * 審核人員
     */
    @PdfValue(colName = "審核人員:",typeFile = 0)
    private String auditPerson;

    /**
     * 審核狀態(tài)
     */
    @PdfValue(colName = "審核狀態(tài):",typeFile = 0)
    private String auditStatus;

    /**
     * 審核時間
     */
    @PdfValue(colName = "審核時間:",typeFile = 0)
    private String auditTime;

    /**
     * 活動名稱
     */
    @PdfValue(colName = "活動名稱:",typeFile = 0)
    private String auctionName;

    /**
     * 競賣類型
     */
    @PdfValue(colName = "競賣類型:",typeFile = 0)
    private String auctionType;

    /**
     * 起止時間
     */
    @PdfValue(colName = "起止時間:",typeFile = 0)
    private String auctionTime;

    /**
     * 延時周期
     */
    @PdfValue(colName = "延時周期:",typeFile = 0)
    private String delayPeriod;

}

字段注解

package com.wanmi.sbc.auction.pdf;

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PdfValue {

    String colName() default "";
    int typeFile() default 0;//0-普通 不用邊框 1-有邊框

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容