js导出excel报表(包括多个工作簿sheet导出)

  1. 要完成导出样式如下图


    导出报表excel格式.png
  • 1-4行:标题
  • 5-12行:项目的基本信息 inputProData
  • 13-20行:项目的指标信息 indexsArray(每种指标的数量不固定)
  1. 需要的数据和格式:
    2.1 inputProData是个对象{},基本信息以键值对的方式存在inputProData对象中。
    2.2 indexsArray是个数组[], 每一条指标信息对应一个indexsArray[i]。
    具体数据格式如下图。ps:这里假设已获取了下图这些数据。


    inputProData
indexsArray
  1. HTML
  • 这里讲1.单条导出2.批量导出,单条导出从页面获取数据导出成excel,批量导出从后台获取数据。批量导出是导出一个excel多个工作簿sheet
  • 按钮绑定事件如下图。
<span  onclick="doInputImport()">单条导出</span>
<span  onclick="doInputeExp()">批量导出</span>
  • 要引入 'jszip', 'bolb', 'xlsx', 'fileSaver' JS!!! jszip引用要放在最前面。
  1. JS
  • 单条导入

先定义一个exlFun 对象,存放关于excel导出的方法

var  exlFun = {};
//后面格式转换要用到
var capital = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var digit = [1, 26, 676, 17576];
var capital_zero = "-0ABCDEFGHIJKLMNOPQRSTUVWXYZ";

单条导入方法:doInputImport

doInputImport= function(){
        //TODO 1.从页面获取数据  标题数据通过项目名称拼凑
        var inputProData = operateData.getDataFromDiv('inputProInfo');//基本信息
        var indexsArray = viewModel.indexsGridDataTable.getSimpleData();//指标信息
        //TODO 2.拼凑excel数据数据格式并导出   PRJ_NAME存放项目名称
        exlFun.creatExcel(inputProData,indexsArray,null,inputProData.PRJ_NAME+"项目支出绩效目标申报表",'nobatch'); 
}

exlFun.creatExcel:


//创建excel并导出(这里因为实际项目原因,将批量导出和单条导出写一起了,可以先只看非批量的导出)
/**
  *  inputProData:项目基本信息(批量处理时inputProData传的是所有要导出项目的信息,包括每个项目的基本信息和指标信息)
  *  indexsArray:项目指标信息
  *  opt:可为空null
  *  fileName:excel文件名称
  *  type 
  **/
exlFun.creatExcel = function(inputProData,indexsArray,opt,fileName,type){
    opt = opt || {};
        if(type == 'nobatch'){//非批量
                opt.proData = inputProData;//存放项目信息
                opt.indexsData = indexsArray;//存放指标信息
                //文件名称(如果未传fileName,以导出文件加日期命名)
                fileName = fileName || "导出文件" + getCurrentDate() + ".xlsx";
                if (fileName.slice(-5).toLowerCase() != '.xlsx') {
                    fileName = fileName + ".xlsx";
                }
                //将网页项目数据转换成excle数据格式sheet
                var sheet = exlFun.getExcelSheet(opt, fileName);
                //导出(下载)excel
                exlFun.saveExcelFile(sheet, fileName);
         }else{//批量
                var sheets = [];var proNames = [];//分开存放每个项目sheet
                //获取不同项目的基本数据
                for(var i=0; i<inputProData.length; i++){
                    var proData = inputProData[i].targetPro;
                    var indexsData = inputProData[i].targetIdx;
                                //将数据的null-->''
                    comFun.dealUndefine(proData);
                    comFun.dealArrOrObjUndefine(indexsData);
                    ////将网页项目数据转换成excle数据格式sheet
                    opt.proData = proData;//项目信息
                    opt.indexsData = indexsData;//指标信息
                    var sheet = exlFun.getExcelSheet(opt, fileName);
                    //将单个项目sheet放入sheets数组
                    sheets.push(sheet);
                    proNames.push(proData.PRJ_NAME);
                }   
                //文件名
                fileName = fileName || "导出文件" + getCurrentDate() + ".xlsx";//文件名称
                if (fileName.slice(-5).toLowerCase() != '.xlsx') {
                    fileName = fileName + ".xlsx";
                }
                //导出(下载)excel多个工作簿sheet
                exlFun.saveBatchExcelFile(sheets,fileName,proNames);//opt放所有sheets
            }
  }

exlFun.getExcelSheet:

exlFun.getExcelSheet = function(opt, fileName){
            var maxHeadRow = 4;//表头 4行
            var maxHeadCol = 9;//表格 9列 :A-I
            //excel总行数:表头+指标数据行数+指标标题行数+项目信息行数
            var rowsLength = maxHeadRow + opt.indexsData.length + 1 + 8;
            opt.maxHeadCol = 9;
            var colWidth = [];//存放列宽
            var rowHeight = [];//存放行高
            var sheet = {
                      '!merges': [],//存放单元格合并信息
                      'A2': {//标题放在A2单元格,见图1 (标题=项目名称+fileName文件名称)
                            v: opt.proData.PRJ_NAME+fileName.replace(".xlsx",""),
                      },
                      'A3': {
                            v: "( 2018年度)",
                      },
                      '!ref': 'A1:I4',
            }
            //设置标题单元格样式style  加粗,黑色,居中显示
            sheet["A2"].s = { font: { sz: 14, bold: true, color: { rgb: "000000" } }, 
                              alignment: {horizontal: "center" ,vertical: "center"}
                             /* fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FFFF00" } }*/
            };
            sheet["A3"].s = { font: { sz: 14, bold: false, color: { rgb: "000000" } }, 
                      alignment: {horizontal: "center" ,vertical: "center"}
            };
            //获取不同指标级的行数
            var indexsTypeNum =  exlFun.getIndexTypeNum(opt.indexsData);
            //获取合并单元格信息
            var sheet = exlFun.getMerges(sheet,rowsLength,indexsTypeNum);
//          console.log(sheet['!merges']);
            //将项目基本信息加入sheet
            sheet = exlFun.getExcelProData (opt,sheet);
            //将项目指标信息加入sheet
            sheet = exlFun.getExcelIndexsData(opt,sheet,rowsLength,maxHeadCol,indexsTypeNum)
            //设置excel范围 :A1:I34
            sheet['!ref'] = 'A1:' +  exlFun.index2ColName(maxHeadCol) + rowsLength;
            sheet["!cols"] = colWidth;
            sheet["!rows"] = rowHeight;
            //设置列宽为100
            for(var n = 0; n < maxHeadCol; n++){  
                sheet['!cols'].push({  
                    wpx: 100  
                 });
            }  
            sheet.maxHeadRow = maxHeadRow;/excel表头标题行数
            sheet.maxHeadCol = maxHeadCol;//excel列数
            sheet.rowLenght = opt.indexsData.length + 1 + 8;//excel行数
            return sheet;
        }

        //index转为列名,如:28 转为 AB
        exlFun.index2ColName = function(index) {
            var colName = "";
            var j = 0;
            for (var i = digit.length - 1; i >= 0; i--) {
                j = Math.floor(index / digit[i]);
                if (j > 0) {
                    colName += capital[j - 1];
                    index = index % digit[i];
                } else {
                    if (colName.length > 0) {
                        colName += "0"
                    }
                }
            }
            colName = colName.split("");
            for (var x = colName.length - 1; x >= 0; x--) {
                if (colName[x] == "0") {
                    //向高位借位处理0
                    if (colName.join("").substring(0, x).replace(/0/g, "") != "") { 
                        colName[x] = "Z";
                        colName[x - 1] = capital_zero[capital_zero.indexOf(colName[x - 1]) - 1];
                    } else {
                        break;
                    }
                } else if (colName[x] == "-") {  //向高位借位,还低位的借位
                    colName[x] = "Y";
                    colName[x - 1] = capital_zero[capital_zero.indexOf(colName[x - 1]) - 1];
                }
            }
            return colName.join("").replace(/0/g, "");
        }

合并单元格 exlFun.getMerges:

合并单元格

例如:项目名称单元格A5,从第0行,第0列开始,在第0行,第3列结束。这路合并信息都是从0开始计算。单元格合并信息为:

sheet['!merges'].push({//项目名称
       s: {r: 0, c: 0},//s指start:开始,r指row:行 ,c指col:列
       e: {r: 0, c: 2}//e指end:结束
})
/**
 *  sheet:excel数据,存放sheet['!merges']
 *  rowsLength:行数
 *  indexsTypeNum:不同级次的指标个数
 **/
       exlFun.getMerges = function(sheet,rowsLength,indexsTypeNum){
           for(var i=0; i<rowsLength-1; i++){
               //行合并 - 项目信息
               if(i == 0 || i == 1){//row:1-2  col:0-8
                   sheet['!merges'].push({
                          s: {r: i+1, c: 0},
                          e: {r: i+1, c: 8}
                   })
               }else if(i == 2 ){
                   
               }else if(i == 3){//row:4  col:0-2 / 3-8
                   sheet['!merges'].push({
                          s: {r: i+1, c: 0},
                          e: {r: i+1, c: 2}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 3},
                          e: {r: i+1, c: 8}
                   });
               }else if(i == 4 || i == 5){//row:5-6  col:0-2 / 3-4 / 5-6 / 7-8
                   sheet['!merges'].push({
                          s: {r: i+1, c: 0},
                          e: {r: i+1, c: 2}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 3},
                          e: {r: i+1, c: 4}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 5},
                          e: {r: i+1, c: 6}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 7},
                          e: {r: i+1, c: 8}
                   });
               }else if(i == 6 || i == 7 || i == 8){//row:7-9  col:0-2/5-6/7-8
                   sheet['!merges'].push({
                          s: {r: i+1, c: 5},
                          e: {r: i+1, c: 6}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 7},
                          e: {r: i+1, c: 8}
                   });
               }else if(i == 9 || i == 10){//row:10-11  col:1-4/5-8
                   sheet['!merges'].push({
                          s: {r: i+1, c: 1},
                          e: {r: i+1, c: 4}
                   });
                   sheet['!merges'].push({
                          s: {r: i+1, c: 5},
                          e: {r: i+1, c: 8}
                   });
               }else{//row:12-end  col:6-7
                   sheet['!merges'].push({
                          s: {r: i+1, c: 6},
                          e: {r: i+1, c: 7}
                   });
               }
           }
           
           //列合并-一二级指标 
           var indexsMer = exlFun.getColMer(indexsTypeNum); 
           for(var m=0; m<indexsMer.length; m++){
               sheet['!merges'].push(indexsMer[m]);
           }
           
           //项目信息
           sheet['!merges'].push({//项目资金
                  s: {r: 7, c: 0},
                  e: {r: 9, c: 2}
           })
           sheet['!merges'].push({//总体目标
                  s: {r: 10, c: 0},
                  e: {r: 11, c: 0}
           })
           //指标信息
           sheet['!merges'].push({//绩效指标
                  s: {r: 12, c: 0},
                  e: {r: rowsLength-1, c: 0}
           })
           sheet['!merges'].push({//总体目标
                  s: {r: 10, c: 0},
                  e: {r: 11, c: 0}
           })
           return sheet
       }


项目基本信息加入sheet :exlFun.getExcelProData

//获取excel项目数据,这个也是根据excel模板(有固定数据和动态数据)
        exlFun.getExcelProData = function(opt,sheet){
             var proDatas = opt.proData;
             sheet['A5'] = {"v": "项目名称"};//固定
             sheet['A6'] = {"v": "主管部门及代码"};
             sheet['A7'] = {"v": "项目属性"};
             sheet['A8'] = {"v": "项目资金(万元)"};
             sheet['A11'] = {"v": "总体目标"};
             sheet['A13'] = {"v": "绩效指标 "};
             sheet['B11'] = {"v": "中期目标(20××年—20××+n年)"};
             sheet['B13'] = {"v": "一级指标"};
             sheet['C13'] = {"v": "二级指标"};
             sheet['D8'] = {"v": "中期资金总额"};
             sheet['D9'] = {"v": "其中:财政拨款"};
             sheet['D10'] = {"v": "其他资金"};
             sheet['D13'] = {"v": "三级指标"};
             sheet['D5'] = {"v": proDatas.PRJ_NAME};//项目名称 动态
             sheet['D6'] = {"v": proDatas.MGR_DEPT_CODE+proDatas.MGR_DEPT_NAME};//主管部门代码名称
             sheet['D7'] = {"v": proDatas.PRJ_KIND};//项目属性
             sheet['E13'] = {"v": "指标值"};
             sheet['E8'] = {"v": proDatas.MTT_AMOUNT};//中期资金总额
             sheet['E9'] = {"v": proDatas.MTF_AMOUNT};//其中:财政拨款
             sheet['E10'] = {"v": proDatas.MTO_AMOUNT};//其他资金
             sheet['F6'] = {"v": "实施单位"};
             sheet['F7'] = {"v": "项目期"};
             sheet['F8'] = {"v": "年度资金总额"};
             sheet['F9'] = {"v": "其中:财政拨款"};
             sheet['F10'] = {"v": "其他资金"};
             sheet['F11'] = {"v": "年度目标"};
             sheet['F13'] = {"v": "二级指标"};
             sheet['G13'] = {"v": "三级指标"};
             sheet['H6'] = {"v": proDatas.EXEC_DEPT_NAME};//实施单位
             sheet['H7'] = {"v": "开始-结束"};//项目期
             sheet['H8'] = {"v": proDatas.YT_AMOUNT};// 年度资金总额
             sheet['H9'] = {"v": proDatas.YF_AMOUNT};//其中:财政拨款
             sheet['H10'] = {"v": proDatas.YO_AMOUNT};//其他资金
             sheet['I13'] = {"v": "指标值"};   
             return sheet//返回sheet
        }

获取excel指标数据: exlFun.getExcelIndexsData

        exlFun.getExcelIndexsData = function(opt,sheet,rowsLength,maxHeadCol,indexsTypeNum){
             var proDatas = opt.indexsData;
             var indexsIndex = exlFun.getRowIndexs(indexsTypeNum);//指标行数下标
             var indexsRow1 =  indexsIndex.indexRows1; 
             var indexsRow2 =  indexsIndex.indexRows2;
             console.log();
             var lengths1 = indexsTypeNum.levelLength1;//[14,7]
             var lengths2 = indexsTypeNum.levelLength2;//[14,7]
             for (var r = 0; r <= rowsLength; r++) {//r:excel行
                 for (var c = 0; c < maxHeadCol; c++) {//c:excel列
                     var addrIndex =  exlFun.index2ColName(c + 1);//A-I 
                     if(r >= 13){//指标开始行
                         for(var a=0; a<indexsRow1.length; a++){
                             if( (indexsRow1[a]+1) == r  && (addrIndex == 'B') ){//一级指标
                                 sheet[addrIndex + r] = {"v": proDatas[r-14].LEVEL1_INDEX};
                             }
                         }
                         for(var b=0; b<indexsRow2.length; b++){
                             if( (indexsRow2[b]+1) == r  && (addrIndex == 'C' || addrIndex == 'F') ){//二级指标
                                 sheet[addrIndex + r] = {"v": proDatas[r-14].LEVEL2_INDEX};
                             }
                         }
                        if(r > 13){//14...
                             for(var o=0; o<proDatas.length; o++){//三级指标和指标值
                                 sheet['D' + r] = {"v": proDatas[r-14].LEVEL3_INDEX};
                                 sheet['E' + r] = {"v": proDatas[r-14].INDEX_VAL};
                                 sheet['G' + r] = {"v": proDatas[r-14].LEVEL3_INDEX_YEAR};
                                 sheet['I' + r] = {"v": proDatas[r-14].INDEX_VAL_YEAR};
                             }  
                        }
                            
                     }
                 }
             }
             return sheet
        }

单条导出:exlFun.saveExcelFile

//利用Blob将数据转换成excel格式
        exlFun.saveExcelFile = function(sheet, fileName){
             var wb = {
                   SheetNames: ['Sheet1'],
                   Sheets: {
                         'Sheet1': sheet
                   }
             };
             var wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};
             //要引入xlsx.js
             var wbout = XLSX.write(wb, wopts);
             saveAs(new Blob([s2ab(wbout)], {type: ""}), fileName);
        }

        //String转换为ArrayBuffer
        function s2ab(s) {
            var buf = new ArrayBuffer(s.length);
            var view = new Uint8Array(buf);
            for (var i = 0; i < s.length; ++i) {
                view[i] = s.charCodeAt(i) & 0xFF;
            }
            return buf;
        }

其他处理指标数据的方法:

 //获取不同类型指标数量
        exlFun.getIndexTypeNum = function(indexsData){
            var levelLength = {};
            levelLength.levelLength1 = [];//不同一级指标的个数
            levelLength.levelLength2 = [];//不同二级指标的个数
            var index1 = 0,index2 = 0;
            for(var i=0; i<indexsData.length; i++){
                 var num1 = 0;var num2 = 0;
                 if(indexsData[i].LEVEL1_INDEX){
                     if(i!=0){//不是第一个 指标一
                         num1 = i-index1;//指标个数
                         index1 = i;
                         levelLength.levelLength1.push(num1);
                     }
                 }
                 if(indexsData[i].LEVEL2_INDEX){
                     if(i!=0){//不是第一个 指标二
                         num2 = i-index2;//指标个数
                         index2 = i;
                         levelLength.levelLength2.push(num2);
                     }
                 }
                 if(i == indexsData.length-1){//判断最后一行指标
                     if(!indexsData[i].LEVEL1_INDEX){//最后一行没有指标一
                         num1 = i+1-index1;
                         index1 = i;
                         levelLength.levelLength1.push(num1);
                     }else{
                         levelLength.levelLength1.push(1);//最后一行单独的指标一
                     }
                     
                     if(!indexsData[i].LEVEL2_INDEX){
                         num2 = i+1-index2;
                         index2 = i;
                         levelLength.levelLength2.push(num2);
                     }else{
                         levelLength.levelLength2.push(1);
                     }
                     
                 }
            }
            return levelLength
        }     
       //获取一二级指标名称的行数
        exlFun.getRowIndexs = function(indexsTypeNum){
            var rowIndex = {};
            var lengths1 = indexsTypeNum.levelLength1;//[14,7]
            var lengths2 = indexsTypeNum.levelLength2;//[14,7]
            var indexRows1 = exlFun.getRowIndex(lengths1);
            var indexRows2 = exlFun.getRowIndex(lengths2);
            rowIndex.indexRows1 = indexRows1;
            rowIndex.indexRows2 = indexRows2;   
            return rowIndex
        }
        //获取某级指标名称行下标
        exlFun.getRowIndex = function(lengths){
            var startRow = 13;
            var n = 0,rows = [];
            rows.push(startRow);
            for(var k=0; k<lengths.length-1; k++){
                n = lengths[k]; 
                startRow = startRow + n;    
                rows.push(startRow);
            }
            return rows
        }
       //指标单元格信息
        exlFun.getColMer = function(indexsTypeNum){
            var startRow1 = 13;
            var startRow2 = 13;
            var lengths1 = indexsTypeNum.levelLength1;//一级指标数量数组[14,6]
            var lengths2 = indexsTypeNum.levelLength2;//一级指标数量数组[14,6]
            var n = lengths1[0];
            var m = lengths2[0];
            var indexsMer = [];
            for(var k=1; k<=lengths1.length; k++){
                //13~26/27~33(end) -->col:1 
                var indexMer1 = {
                    s: {r: startRow1, c: 1},
                    e: {r: startRow1 + n - 1, c: 1}//TODO r:i+产出指标/效果指标个数 12+14=26  26+7=33 
                };
                startRow1 = startRow1 +n;
                n = lengths1[k];    
                indexsMer.push(indexMer1);
            }
            for(var k=1; k<=lengths2.length; k++){
                //13~16/17~19/20~22 -->col:2 /5
                var indexMer2 = {
                    s: {r: startRow2, c: 2},
                    e: {r: startRow2 + m - 1, c: 2}//TODO r:i+产出指标/效果指标个数 12+14=26  26+7=33 
                };
                var indexMer3 = {
                    s: {r: startRow2, c: 5},
                    e: {r: startRow2 + m - 1, c: 5}//TODO r:i+产出指标/效果指标个数 12+14=26  26+7=33 
                };
                startRow2 = startRow2 +m;
                m = lengths2[k];    
                indexsMer.push(indexMer2);
                indexsMer.push(indexMer3);
            }
            return indexsMer
        }
  • 批量导出
    批量导出就获取数据的方法、 exlFun.saveExcelFile方法略有不同。
/**
         * 批量导出
         */
        doBatchExp = function(){
            //TODO 1.根据CHR_ID从后台获取数据
            var currViewModel =  comFun.getCurrViewModel();//判断当前活动页
            ids = currViewModel.gridData.getSimpleData({//获取选择的行CHR_ID
                type : 'select',
                fields : [ 'CHR_ID' ]
            });
            if (ids == 0) {
                ip.ipInfoJump("请至少选择一条数据!", "error");
                return;
            }
            var batchProDatas = [];//存放不同项目数据
            ids.forEach(function(obj){
                 //TODO 从后台获取每条数据的项目信息和指标信息,放在detailsObj 
                 var detailsObj = ajaxObj.batchExp(obj.CHR_ID);
                 batchProDatas.push(detailsObj);
            })
            //TODO 批量导出,方法同单条导出,参数意义不同
             exlFun.creatExcel(batchProDatas,null,null,"项目支出绩效目标申报表",'batch');  
        }

利用Blob将数据转换成excel格式 -- 批量:exlFun.saveBatchExcelFile

        exlFun.saveBatchExcelFile = function(sheetArr,fileName,proNames){           
            var wb = {
                       SheetNames: [],
                       Sheets: {},
             };
             for(var i=0; i<sheetArr.length; i++ ){
                 wb.SheetNames.push('Sheet'+(i+1));
                 wb.Sheets['Sheet'+(i+1)] = sheetArr[i]
                 //以下代码可以替换页签(工作簿名称),但要保证名称一定不同
                 /*wb.SheetNames.push(proNames[i]);
                 wb.Sheets[proNames[i]] = sheetArr[i];*/
             }
             var wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};
             var wbout = XLSX.write(wb, wopts);//xlsx.js
             saveAs(new Blob([s2ab(wbout)], {type: ""}), fileName);
        }
        //String转换为ArrayBuffer
        function s2ab(s) {
            var buf = new ArrayBuffer(s.length);
            var view = new Uint8Array(buf);
            for (var i = 0; i < s.length; ++i) {
                view[i] = s.charCodeAt(i) & 0xFF;
            }
            return buf;
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容