`
longgangbai
  • 浏览: 7374466 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ireport导出各种格式(pdf,excel,word,html,print)

 
阅读更多
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

/**
 * 使用jasperReport做报表时的工具支持类.有两个用途,生成jasperPrint对象,和设置导出时的session
 */
public class ReportUtils {
    private HttpServletRequest request;
    private HttpServletResponse response;
    private HttpSession session;

    /**
     * 在其它web环境下构造此工具类对象
     * 
     * @param request
     *            request请求对象
     */
    public ReportUtils(HttpServletRequest request) {
        this.request = request;
        this.session = request.getSession();
    }

    public ReportUtils(HttpServletResponse response) {
        this.response = response;
    }

    public ReportUtils(HttpServletRequest request, HttpServletResponse response) {
        this(request);
        this.response = response;
    }

    /**
     * 获得JasperPrint对象;自定义填充报表时的parameter和dataSource. 参数说明和动态表头的用法参考上一方法
     * 
     * @param filePath
     * @param parameter
     * @param dataSource
     * @param sizeGroup
     * @return
     */
    public JasperPrint getJasperPrint(String filePath, Map parameter,
            JRDataSource dataSource) throws JRException {
        JasperReport jasperReport = null;
        try {
            jasperReport = (JasperReport) JRLoader.loadObject(filePath);
            return JasperFillManager.fillReport(jasperReport, parameter,
                    dataSource);
        } catch (JRException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过传入List类型数据源获取JasperPrint实例
     * 
     * @param filePath
     *            jasper路径
     * @param parameter
     * @param list
     * @return
     * @throws JRException
     */
    public JasperPrint getPrintWithBeanList(String filePath, Map parameter,
            List list) throws JRException {
        JRDataSource dataSource = new JRBeanCollectionDataSource(list);
        return getJasperPrint(filePath, parameter, dataSource);
    }

    /**
     * 传入类型,获取输出器
     * 
     * @param docType
     * @return
     */
    public JRAbstractExporter getJRExporter(DocType docType) {
        JRAbstractExporter exporter = null;
        switch (docType) {
        case PDF:
            exporter = new JRPdfExporter();
            break;
        case HTML:
            exporter = new JRHtmlExporter();
            break;
        case XLS:
            exporter = new JExcelApiExporter();
            break;
        case XML:
            exporter = new JRXmlExporter();
            break;
        case RTF:
            exporter = new JRRtfExporter();
            break;
        }
        return exporter;
    }

    public void setAttrToPage(JasperPrint jasperPrint, String report_fileName,
            String report_type) {
        session.setAttribute("REPORT_JASPERPRINT", jasperPrint);
        session.setAttribute("REPORT_FILENAME", report_fileName);
        session.setAttribute("REPORT_TYPE", report_type);
    }

    /**
     * 定义了报表输出类型,固定了可输出类型
     * 
     * @author Administrator
     * 
     */
    public static enum DocType {
        PDF, HTML, XLS, XML, RTF
    }

    /**
     * 编译报表模板文件jaxml,生成jasper二进制文件
     * 
     * @param jaxmlPath
     * @param jasperPath
     * @throws JRException
     */
    public void complieJaxml(String jaxmlPath, String jasperPath)
            throws JRException {
        JasperCompileManager.compileReportToFile(jaxmlPath, jasperPath);
    }

    /**
     * 输出PDF 使用此方法,必须预先注入response
     * 
     * @param jasperPath
     * @param params
     * @param sourceList
     * @param fileName
     * @throws JRException
     * @throws IOException
     * @throws ServletException
     */
    public void servletExportPDF(String jasperPath, Map params,
            List sourceList, String fileName) throws JRException, IOException,
            ServletException {
        servletExportDocument(DocType.PDF, jasperPath, params, sourceList,
                fileName);
    }

    /**
     * 输出html静态页面,必须注入request和response
     * 
     * @param jasperPath
     * @param params
     * @param sourceList
     * @param imageUrl
     *            报表文件使用的图片路径,比如 ../servlets/image?image=
     * @throws JRException
     * @throws IOException
     * @throws ServletException
     */
    public void servletExportHTML(String jasperPath, Map params,
            List sourceList, String imageUrl) throws JRException, IOException,
            ServletException {
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        JRAbstractExporter exporter = getJRExporter(DocType.HTML);

        JasperPrint jasperPrint = getPrintWithBeanList(jasperPath, params,
                sourceList);

        session.setAttribute(
                ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
                jasperPrint);

        PrintWriter out = response.getWriter();

        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
        exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, imageUrl);
        exporter.exportReport();
    }

    /**
     * 输出Excel报表文件
     * 
     * @param jasperPath
     * @param params
     * @param sourceList
     * @param fileName
     * @throws JRException
     * @throws IOException
     * @throws ServletException
     */
    public void servletExportExcel(String jasperPath, Map params,
            List sourceList, String fileName) throws JRException, IOException,
            ServletException {
        servletExportDocument(DocType.XLS, jasperPath, params, sourceList,
                fileName);
        // 要想获得更好的视觉效果,可以添加以下代码
        // // exporter.setParameter(
        // // JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
        // // Boolean.TRUE); // 删除记录最下面的空行
        // //
        // exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
        // // Boolean.FALSE);// 删除多余的ColumnHeader
        // //
        // exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND
        // ,
        // // Boolean.FALSE);// 显示边框
    }

    /**
     * 生成不同格式报表文档
     * 
     * @param docType
     *            文档类型
     * @param jasperPath
     * @param params
     * @param sourceList
     * @param fileName
     * @throws JRException
     * @throws IOException
     * @throws ServletException
     */
    public void servletExportDocument(DocType docType, String jasperPath,
            Map params, List sourceList, String fileName) throws JRException,
            IOException, ServletException {

        if (docType == DocType.HTML) {
            servletExportHTML(jasperPath, params, sourceList, fileName);
            return;
        }

        JRAbstractExporter exporter = getJRExporter(docType);
        // 获取后缀
        String ext = docType.toString().toLowerCase();

        if (!fileName.toLowerCase().endsWith(ext)) {
            fileName += "." + ext;
        }
        // 判断资源类型
        String contentType = "application/";
        if (ext.equals("xls")) {
            ext = "excel";
        } else if (ext.equals("xml")) {
            contentType = "text/";
        }
        contentType += ext;

        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment; filename=\""
                + URLEncoder.encode(fileName, "UTF-8") + "\"");

        exporter.setParameter(JRExporterParameter.JASPER_PRINT,
                getPrintWithBeanList(jasperPath, params, sourceList));

        OutputStream ouputStream = response.getOutputStream();

        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
        try {
            exporter.exportReport();
        } catch (JRException e) {
            throw new ServletException(e);
        } finally {
            if (ouputStream != null) {
                try {
                    ouputStream.close();
                } catch (IOException ex) {
                }
            }
        }
    }
}

 iReport+jasperReport之CSV、XML数据源

jasperReport支持多种格式的数据源,CSV(Comma Separated values),是一种用来存储数据的纯文本,文件格式,通常用于电子表格或数据库软件。

规则

0 开头是不留空,以行为单位。
1 可含或不含列名,含列名则居文件第一行。
2 一行数据不垮行,无空行。
3 以半角符号,作分隔符,列为空也要表达其存在。
4 列内容如存在,,则用“”包含起来。
5 列内容如存在“”则用“”“”包含。
6 文件读写时引号,逗号操作规则互逆。
7 内码格式不限,可为ASCII、Unicode或者其他。

jasper文件和前面几篇用到的是一样的(person.jasper),准备数据的文本文件Person.txt其中文件的格式对应模板文件的字段【 "pid", "name", "sex", "age", "password", "department"】。

"20000000001","bulktree1","man","21","1111111111","pcisv61"
"20000000002","bulktree2","man","22","2222222222","pcisv62"
"20000000003","bulktree3","man","23","3333333333","pcisv63"
"20000000004","bulktree4","man","24","4444444444","pcisv64"
"20000000005","bulktree5","man","25","5555555555","pcisv65"
"20000000006","bulktree6","man","26","6666666666","pcisv66"
"20000000007","bulktree7","man","27","7777777777","pcisv67"
"20000000008","bulktree8","man","28","8888888888","pcisv68"
"20000000009","bulktree9","man","29","9999999999","pcisv69"

下来我们看看jasperReport的API是怎么识别这些数据的,但是做这个之前我们还要指定数据到底是怎么对应的,定义String类型数组存放模板对应的列名和文本数据对应

String[] columNames = new String[] "pid""name""sex""age""password",
                
"department" }
;

识别这些数据并不难,下面这一句就可以搞定:

JRCsvDataSource jrcsvDataScource = new JRCsvDataSource(JRLoader
                .getLocationInputStream(
"D:\\workspace\\Person.txt"));

我们怎么才能让它识别对应的列呢?查看API看看对应的set方法吧!

// set record delimiter
        jrcsvDataScource.setRecordDelimiter("\r\n");
        
// set columnName
        jrcsvDataScource.setColumnNames(columNames);

至此数据源就准备完了,jasperReport封装了底层的实现,简单吧!下来看看完整的代码:

package org.bulktree.ireport.csvdata;

import java.util.HashMap;

import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRCsvDataSource;
import net.sf.jasperreports.engine.util.JRLoader;

import org.bulktree.ireport.ViewReport;

public class CSVDataSource {
    
    
public static void main(String[] args) {
        
try {
            
new CSVDataSource().reportView();
        }
 catch (Exception e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    
private void reportView() throws Exception {
        JasperReport jasperReport 
= (JasperReport) JRLoader
                .loadObject(
"D:\\workspace\\Person.jasper");

        JasperPrint jasperPrint 
= JasperFillManager.fillReport(jasperReport,
                getReportParameter(), getDateSource());
        
        
new ViewReport().viewer(jasperPrint);
    }


    
private HashMap getReportParameter() {
        HashMap parameters 
= new HashMap();
        parameters.put(
"reportTitle""laoshulin");
        
return parameters;
    }


    
private JRCsvDataSource getDateSource() throws Exception {
        String[] columNames 
= new String[] "pid""name""sex""age""password",
                
"department" }
;
        
// get csvdata
        JRCsvDataSource jrcsvDataScource = new JRCsvDataSource(JRLoader
                .getLocationInputStream(
"D:\\workspace\\test\\src\\org\\bulktree\\ireport\\csvdata\\Person.txt"));
        
// set record delimiter
        jrcsvDataScource.setRecordDelimiter("\r\n");
        
// set columnName
        jrcsvDataScource.setColumnNames(columNames);

        
return jrcsvDataScource;
    }

}

还是这样的效果吧!^_^



        至于XML数据源也是很简单,通过读取xml文件获得数据

Document document = JRXmlUtils.parse(JRLoader.getLocationInputStream(xmlFileName));

不同的是document会作为一个参数传递给报表,fillReport方法就不会出现第三个参数,完整代码如下:

package org.bulktree.ireport.xmldata;

import java.util.HashMap;
import java.util.Locale;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRXmlUtils;

import org.bulktree.ireport.ViewReport;
import org.w3c.dom.Document;

public class XMLDataSource {

    
private static final String JASPER_FILE_NAME = "D:\\workspace\\Person.jasper";
    
private static final String XML_FILE_NAME = "D:\\workspace\\person.xml";

    
private void viewerReport() throws JRException {
        JasperReport jasperReport 
= (JasperReport) JRLoader.loadObject(JASPER_FILE_NAME);

        JasperPrint jasperPrint 
= JasperFillManager.fillReport(jasperReport,
                getReportParameter(XML_FILE_NAME));

        
new ViewReport().viewer(jasperPrint);
    }


    
private HashMap getReportParameter(String xmlFileName) {
        HashMap parameters 
= new HashMap();
        
try {
            parameters.put(
"reportTitle""laoshulin");
            Document document 
= JRXmlUtils.parse(JRLoader.getLocationInputStream(xmlFileName));

            parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT,
                    document);
            parameters.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, 
"yyyy-MM-dd");
            parameters.put(JRXPathQueryExecuterFactory.XML_NUMBER_PATTERN, 
"#,##0.##");
            parameters.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.CHINESE);
            parameters.put(JRParameter.REPORT_LOCALE, Locale.CHINA);

        }
 catch (JRException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }


        
return parameters;
    }


    
public static void main(String[] args) throws Exception {
        
new XMLDataSource().viewerReport();
    }

}

        预览效果就不看了吧!哈哈 都是一样的道理,现在看看jasperReport的API有多强大了吧!

分享到:
评论
2 楼 laoguan123 2017-11-07  
请教一下,可以导出带颜色等格式的文档吗?
1 楼 アリス 2017-04-13  
请问有没有打包成ZIP在下载的方法

相关推荐

    java调用ireport生成word报告

    ### Java调用iReport...此外,对于需要生成Excel或PDF格式的报告,只需对上述Java代码中的导出部分稍作调整即可。这种方法不仅提高了报表生成的效率,还大大简化了开发流程,非常适合于需要频繁生成报表的应用场景。

    ireport导出excel 部分源码

    除了Excel之外,iReport还可以轻松地导出PDF、HTML和Word等格式。例如,对于PDF导出,可以使用`JasperExportManager`类的静态方法`exportReportToPdfStream()`;而HTML和Word则分别可以通过`JRHtmlExporter`和`...

    ireport 报表常见的问题解决方案

    3.1.1 导出 EXCEL/PDF 分页 在 ireport 中,设置导出报表时的分页是关键,确保每个页面的数据量适中。开发者需要调整报表的分组和页面大小设置,以实现理想的分页效果。 3.1.2 每页显示*页 当需要在每一页底部...

    jasperreports flash 改写

    更改了jasperreports flash的官方版,实现打印,pdf,excel,word的导出,添加了打印后的回调执行,基本问题都已经处理, <param name="movie" value="flash_pb.swf?jrpxml=servlets/xml?<%=parm%>&PRINT_ALL=all&...

    正交频分复用 (OFDM) 基础收发机Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    通信工程勘察设计安全操作规程.docx

    通信工程勘察设计安全操作规程.docx

    【数据库技术】SQL入门与实战指南:从基础语法到应用场景的全面解析

    内容概要:本文是一篇面向初学者和技术爱好者的《SQL 入门与实战》指南,系统介绍了 SQL 的基本概念、功能及其应用场景。文章首先解释了 SQL 是一种用于操作关系型数据库的语言,能够执行数据的存储、查询、更新、删除以及表结构管理等操作。接着详细列举了基础语法,包括 SELECT、INSERT、UPDATE 和 DELETE 等语句的具体用法,并对常用的函数进行了分类说明,如聚合函数、字符串函数、时间函数等。此外,还深入探讨了多表连接、分组与聚合、子查询和窗口函数等进阶语法技巧。为了帮助读者更好地掌握 SQL,文中提供了从初级到高级的学习路线,并通过实际案例展示了 SQL 在后端 API 查询、数据报表分析、数据清洗与迁移等场景中的应用。最后简要比较了几种常见的数据库系统特性,强调了 SQL 在数据处理领域的重要性。 适合人群:适合初学者、实用派和技术爱好者,尤其是那些希望快速上手 SQL 并应用于实际工作的人员,如前端、后端、测试工程师、数据分析师和产品经理等。 使用场景及目标:①作为 SQL 学习入门资料,帮助读者理解 SQL 的基本概念和语法;②指导读者进行 SQL 编程实践,掌握数据查询、更新、插入、删除及表结构管理等操作;③为有经验的开发者提供进阶技巧,如多表连接、子查询、窗口函数等;④为从事数据相关工作的人员提供实用工具,提高工作效率。 其他说明:文章不仅涵盖了 SQL 的基础知识,还涉及到了一些高级主题,如事务、索引、视图、触发器等,并给出了进一步学习的书籍和在线资源推荐,鼓励读者通过持续学习来深化对 SQL 的理解和应用。

    wps办公日常使用11111111

    wps办公日常使用11111111

    卡通小熊素材PPT模板.pptx

    卡通小熊素材PPT模板

    汽车电子:MATLAB_实现CAN总线通信协议分析与故障诊断.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    支付技术基于MCP协议的支付宝AI支付工具集成:支付管理与应用场景详解

    内容概要:本文介绍了国内首个支付MCP(Model Context Protocol)框架,它定义了AI模型如何调用外部支付工具、获取支付数据并与支付服务交互。支付宝与魔搭社区合作,基于支付MCP Server框架为AI智能体提供无缝支付能力。支付MCP Server具有以下特点:支持MCP协议,简化支付接入流程;多端支持,涵盖移动端和网页端支付场景;全流程支付管理,包括支付、查询、退款等功能;灵活配置选项,满足不同开发需求。文中详细描述了支付MCP Server的功能,如创建支付、查询支付状态、发起退款和查询退款信息等,并提供了具体的配置方法和应用场景案例,如AI助手帮助用户在线购物、AI客服处理退款请求等。 适合人群:具有一定编程基础和技术背景的研发人员,尤其是对AI与支付集成感兴趣的开发者。 使用场景及目标:① 开发人员可以通过支付MCP Server快速实现支付功能,简化开发流程;② 提供全流程支付管理,增强应用的支付处理能力;③ 支持多端支付场景,提升用户体验;④ 通过灵活配置,满足不同业务需求,创造更多商业机会。 阅读建议:此资源详细介绍了支付M

    环境工程:MATLAB_实现大气污染扩散模型与可视化分析.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    【充电桩通信技术】基于云快充最新版协议的充电桩与新能源管理系统交互流程及数据格式定义:涵盖通信接口、帧类型、实时数据与运营交互等详细规范标题严格按照您的要求

    内容概要:本文档详细介绍了云快充最新版本的充电桩通讯协议,涵盖了从总则、通信协议结构、应用层报文帧格式、帧类型定义、通信协议流程、注册心跳帧类型码、实时数据帧类型码、运营交互帧类型码、运营平台设置帧类型码、车位锁通信协议、电桩远程维护帧类型码、并充模式帧类型码到附录的完整内容。重点描述了充电桩与新能源管理信息系统之间的数据交互流程、格式和内容,明确了通信接口采用TCP/IP Socket方式,支持有线网络接口和无线GPRS连接。文档还具体阐述了帧结构、数据格式定义、名词解释、各种帧类型的数据定义及流程,如上电流程、APP充电流程、刷卡充电、离线充电模式等,并提供了CRC16校验计算方法。 适合人群:从事充电桩开发、运维的技术人员,以及负责充电桩与平台对接的工程师。 使用场景及目标:①指导技术人员完成充电桩与新能源管理信息系统的对接,确保数据交互的正确性和稳定性;②帮助工程师理解并实现充电桩的各种功能,如登录认证、心跳包、实时数据传输、远程控制等;③为充电桩的日常维护和远程更新提供技术支持。 其他说明:本协议适用于交直流充电桩,交流部分数据无需上送。协议基于国网104充电桩规约,并参考GBT-27930标准。测试服务器地址为121.199.192.223,端口号为8768。文档还提供了详细的帧类型码定义和CRC16校验计算方法,确保数据传输的准确性。

    监理网站推广方案.docx

    监理网站推广方案.docx

    HI3519DV500 配置无线网依赖库以及编译脚本

    HI3519DV500 配置无线网依赖库以及编译脚本

    Clion和MinGW

    Clion和MinGW

    hardware-MLK-F6-7020.rar

    hardware_MLK-F6-7020.rar

    如何查看死锁.md

    如何查看死锁

    定制小米8-lineage22.1安卓15-fast功能项目线刷双版root 解锁bl后fast线刷

    资源说明; 1-----刷写前提是手机必须解锁bl先。而且会在fast模式刷写固件 2-----刷写方法与官方刷写步骤一样 3-----此固件为定制初始固件。可以在fast模式刷写 4-----属于适配固件。也许有个别bug。不接受请勿下载 5-----需要一定的刷机常识与动手能力的友友刷写。 6-----资源有可复制性。下载后不支持退。请知悉 7-----定制其他需求可以在csdn私信博主 博文参阅:https://csdn9.blog.csdn.net/article/details/143058308

    敏感图片敏感图片敏感图片敏感图片敏感图片敏感图片11

    敏感图片敏感图片敏感图片敏感图片敏感图片敏感图片11敏感图片敏感图片敏感图片敏感图片敏感图片敏感图片1122

Global site tag (gtag.js) - Google Analytics