Poi 導(dǎo)入Excel表格SAX(事件)

采用讀取csv格式,類似讀取txt文檔

接收前端請(qǐng)求的controller層

前端代碼使用的Vue upload主鍵,返回值一般就是讀取成功或失敗

@RequestMapping(value = "/importExcelDatas.do", method = RequestMethod.POST)
    @ResponseBody
    public ResultData importExcelDatas(HttpServletRequest request,HttpServletResponse response) {
        ResultData resultData = new ResultData();
        try {
            resultData = importDataService.importExcelDatas(request, response);
        } catch (Exception e) {
            e.printStackTrace();
            resultData.setResult(false);
            log.error(e.getMessage(), e);
        }
        return  resultData;
    }
處理數(shù)據(jù)Service層
public ResultData importExcelDatas(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ResultData resultData = new ResultData();
        //轉(zhuǎn)換請(qǐng)求
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                //獲取請(qǐng)求中的上傳文件名 迭代器
        Iterator<String> iter = multipartRequest.getFileNames();
        List<String[]> list  = new ArrayList<>();
        MultipartFile multipartFile=null;
        Map<String,List<Map<String, String>>> superMap = null;
        while (iter.hasNext()) {
            String filefiled = iter.next();
                          //或得上傳文件
             multipartFile = multipartRequest.getFile(filefiled);
                          //因?yàn)槭录J较碌淖x取是在工具類里盜用我們的處理方法所以把必要的數(shù)據(jù)傳過(guò)去,這里可忽略給自己提醒看的
            /* importDataServiceimpl importService = new importDataServiceimpl();
             importService.response = response;
             importService.request=request;
             importService.tenantCode = tenantCode;
             importService.multipartFile = multipartFile;
             importService.importName = importName;
             importService.mbrMemberLocationServiceImpl=this.mbrMemberLocationServiceImpl;
             importService.mbrCategoryDao = this.mbrCategoryDao;
             importService.sysComboCodeDao=this.sysComboCodeDao;
             importService.handleLogService=this.handleLogService;
             importService.mbrMemberService=this.mbrMemberService;
             importService.mbrImportNotSuccessDao = this.mbrImportNotSuccessDao;
             importService.mbrMemberLocationDao=this.mbrMemberLocationDao;
            */
             try {
                                //讀取的過(guò)程
                 ExcelReaderUtils.readExcel(importService,multipartFile);
            } catch (Exception e) {
                logger.error(e.getMessage());
                resultData.setResult(false);
                resultData.setMessage("讀取文件失敗,請(qǐng)檢查文件!");
                return resultData;
            }
        }
        resultData.setResult(true);
        return resultData;
    }
識(shí)別文件調(diào)用處理類
public class ExcelReaderUtils {

    //excel2003擴(kuò)展名
    public static final String EXCEL03_EXTENSION = ".xls";
    //excel2007擴(kuò)展名
    public static final String EXCEL07_EXTENSION = ".xlsx";
    /**
     * 讀取Excel文件,可能是03也可能是07版本
     * @param excel03
     * @param excel07
     * @throws Exception
     */
    public static void readExcel(importDataServiceimpl importService,MultipartFile multipartFile) throws Exception{
        //multipartFile獲取文件名 判斷文件類型
        String fileName = multipartFile.getOriginalFilename();
           // 處理excel2003文件
           if (fileName.endsWith(EXCEL03_EXTENSION)){
                   Excel2003Reader excel03 = new Excel2003Reader();
                   excel03.process(fileName);
           // 處理excel2007文件
           } else if (fileName.endsWith(EXCEL07_EXTENSION)){
                   Excel2007Reader excel07 = new Excel2007Reader();
                   excel07.process(multipartFile);
           } else {
                   throw new  Exception("文件格式錯(cuò)誤,fileName的擴(kuò)展名只能是xls或xlsx。");
           }
    }
}
處理Excel2003的工具類

這里只貼下代碼沒(méi)做研究

package com.sjky.platform.myapp.importData.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import com.sjky.platform.myapp.importData.service.impl.importDataServiceimpl;

public  class Excel2003Reader implements HSSFListener{
    private int minColumns = -1;
    private POIFSFileSystem fs;
    private int lastRowNumber;
    private int lastColumnNumber;
    /** Should we output the formula, or the value it has? */
    private boolean outputFormulaValues = true;
    /** For parsing Formulas */
    private SheetRecordCollectingListener workbookBuildingListener;
    //excel2003工作薄
    private HSSFWorkbook stubWorkbook;
    // Records we pick up as we process
    private SSTRecord sstRecord;
    private FormatTrackingHSSFListener formatListener;
    //表索引
    private int sheetIndex = -1;
    private BoundSheetRecord[] orderedBSRs;
    @SuppressWarnings("unchecked")
    private ArrayList boundSheetRecords = new ArrayList();
    // For handling formulas with string results
    private int nextRow;
    private int nextColumn;
    private boolean outputNextStringRecord;
    //當(dāng)前行
    private int curRow = 0;
    //存儲(chǔ)行記錄的容器
    private List<String> rowlist = new ArrayList<String>();;
    @SuppressWarnings( "unused")
    private String sheetName;
    /**
     * 遍歷excel下所有的sheet
     * @throws IOException
     */
    public void process(String fileName) throws IOException {
           this.fs = new POIFSFileSystem(new FileInputStream(fileName));
           MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(
                           this);
           formatListener = new FormatTrackingHSSFListener(listener);
           HSSFEventFactory factory = new HSSFEventFactory();
           HSSFRequest request = new HSSFRequest();
           if (outputFormulaValues) {
                   request.addListenerForAllRecords(formatListener);
           } else {
                   workbookBuildingListener = new SheetRecordCollectingListener(
                                   formatListener);
                   request.addListenerForAllRecords(workbookBuildingListener);
           }
           factory.processWorkbookEvents(request, fs);
    }
    /**
     * HSSFListener 監(jiān)聽(tīng)方法,處理 Record
     */
    @SuppressWarnings("unchecked")
    public void processRecord(Record record) {
           int thisRow = -1;
           int thisColumn = -1;
           String thisStr = null;
           String value = null;
           switch (record.getSid()) {
                   case BoundSheetRecord.sid:
                           boundSheetRecords.add(record);
                           break;
                   case BOFRecord.sid:
                           BOFRecord br = (BOFRecord) record;
                           if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
                                  // 如果有需要,則建立子工作薄
                                  if (workbookBuildingListener != null && stubWorkbook == null) {
                                          stubWorkbook = workbookBuildingListener
                                                         .getStubHSSFWorkbook();
                                  }
                                  sheetIndex++;
                                  if (orderedBSRs == null) {
                                          orderedBSRs = BoundSheetRecord
                                                         .orderByBofPosition(boundSheetRecords);
                                  }
                                  sheetName = orderedBSRs[sheetIndex].getSheetname();
                           }
                           break;
                   case SSTRecord.sid:
                           sstRecord = (SSTRecord) record;
                           break;
                   case BlankRecord.sid:
                           BlankRecord brec = (BlankRecord) record;
                           thisRow = brec.getRow();
                           thisColumn = brec.getColumn();
                           thisStr = "";
                           rowlist.add(thisColumn, thisStr);
                           break;
                   case BoolErrRecord.sid: //單元格為布爾類型
                           BoolErrRecord berec = (BoolErrRecord) record;
                           thisRow = berec.getRow();
                           thisColumn = berec.getColumn();
                           thisStr = berec.getBooleanValue()+"";
                           rowlist.add(thisColumn, thisStr);
                           break;
                   case FormulaRecord.sid: //單元格為公式類型
                           FormulaRecord frec = (FormulaRecord) record;
                           thisRow = frec.getRow();
                           thisColumn = frec.getColumn();
                           if (outputFormulaValues) {
                                  if (Double.isNaN(frec.getValue())) {
                                          // Formula result is a string
                                          // This is stored in the next record
                                          outputNextStringRecord = true;
                                          nextRow = frec.getRow();
                                          nextColumn = frec.getColumn();
                                  } else {
                                          thisStr = formatListener.formatNumberDateCell(frec);
                                  }
                           } else {
                                  thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook,
                                                 frec.getParsedExpression()) + '"';
                           }
                           rowlist.add(thisColumn,thisStr);
                           break;
                   case StringRecord.sid://單元格中公式的字符串
                           if (outputNextStringRecord) {
                                  // String for formula
                                  StringRecord srec = (StringRecord) record;
                                  thisStr = srec.getString();
                                  thisRow = nextRow;
                                  thisColumn = nextColumn;
                                  outputNextStringRecord = false;
                           }
                           break;
                   case LabelRecord.sid:
                           LabelRecord lrec = (LabelRecord) record;
                           curRow = thisRow = lrec.getRow();
                           thisColumn = lrec.getColumn();
                           value = lrec.getValue().trim();
                           value = value.equals("")?" ":value;
                           this.rowlist.add(thisColumn, value);
                           break;
                   case LabelSSTRecord.sid:  //單元格為字符串類型
                           LabelSSTRecord lsrec = (LabelSSTRecord) record;
                           curRow = thisRow = lsrec.getRow();
                           thisColumn = lsrec.getColumn();
                           if (sstRecord == null) {
                                  rowlist.add(thisColumn, " ");
                           } else {
                                  value =  sstRecord
                                  .getString(lsrec.getSSTIndex()).toString().trim();
                                  value = value.equals("")?" ":value;
                                  rowlist.add(thisColumn,value);
                           }
                           break;
                   case NumberRecord.sid:  //單元格為數(shù)字類型
                           NumberRecord numrec = (NumberRecord) record;
                           curRow = thisRow = numrec.getRow();
                           thisColumn = numrec.getColumn();
                           value = formatListener.formatNumberDateCell(numrec).trim();
                           value = value.equals("")?" ":value;
                           // 向容器加入列值
                           rowlist.add(thisColumn, value);
                           break;
                   default:
                           break;
           }
           // 遇到新行的操作
           if (thisRow != -1 && thisRow != lastRowNumber) {
                   lastColumnNumber = -1;
           }
           // 空值的操作
           if (record instanceof MissingCellDummyRecord) {
                   MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
                   curRow = thisRow = mc.getRow();
                   thisColumn = mc.getColumn();
                   rowlist.add(thisColumn," ");
           }
           // 更新行和列的值
           if (thisRow > -1)
                   lastRowNumber = thisRow;
           if (thisColumn > -1)
                   lastColumnNumber = thisColumn;
           // 行結(jié)束時(shí)的操作
           if (record instanceof LastCellOfRowDummyRecord) {
                   if (minColumns > 0) {
                           // 列值重新置空
                           if (lastColumnNumber == -1) {
                                  lastColumnNumber = 0;
                           }
                   }
                   lastColumnNumber = -1;
                           // 每行結(jié)束時(shí), 調(diào)用getRows() 方法
                   importDataServiceimpl importMbrServiceimpl = new importDataServiceimpl();
                   try {
                    //importMbrServiceimpl.getRows(sheetIndex,curRow, rowlist);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                   // 清空容器
                   rowlist.clear();
           }
    }
}
處理Excel2007的工具類
package com.sjky.platform.myapp.importData.utils;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import com.sjky.platform.myapp.importData.service.impl.importDataServiceimpl;

/**
 * 抽象Excel2007讀取器,excel2007的底層數(shù)據(jù)結(jié)構(gòu)是xml文件,采用SAX的事件驅(qū)動(dòng)的方法解析
 * xml,需要繼承DefaultHandler,在遇到文件內(nèi)容時(shí),事件會(huì)觸發(fā),這種做法可以大大降低
 * 內(nèi)存的耗費(fèi),特別使用于大數(shù)據(jù)量的文件。
 *
 */
public class Excel2007Reader extends DefaultHandler {
    //共享字符串表
    private SharedStringsTable sst;
    //上一次的內(nèi)容
    private String lastContents;
    //判斷是否是String
    private boolean nextIsString;
    //記錄行數(shù)
    private int sheetIndex = -1;
    //每行結(jié)果集
    private List<String> rowlist = new ArrayList<String>();
    //整個(gè)Excel的集合
    private List<List<String>> excelList = new ArrayList<List<String>>();
    //判斷是否是空單元格
    private boolean cellNull;
    //當(dāng)前行
    private int curRow = 0;
    //當(dāng)前列
    private int curCol = 0;
    //有效數(shù)據(jù)矩形區(qū)域,A1:Y2
    private String dimension;
    //根據(jù)dimension得出每行的數(shù)據(jù)長(zhǎng)度
    private int longest;
    //上個(gè)有內(nèi)容的單元格id,判斷空單元格
    private String lastCellid;
    //處理單行數(shù)據(jù)的類
    private importDataServiceimpl importService;
    private boolean isTElement;
    public void setImpotService(importDataServiceimpl importService){
        
           this.importService = importService;
    }
    /**只遍歷一個(gè)電子表格,其中sheetId為要遍歷的sheet索引,從1開(kāi)始,1-3
     * @param filename
     * @param sheetId
     * @throws Exception
     */
    public void processOneSheet(String filename,int sheetId) throws Exception {
           OPCPackage pkg = OPCPackage.open(filename);
           XSSFReader r = new XSSFReader(pkg);
           SharedStringsTable sst = r.getSharedStringsTable();
           XMLReader parser = fetchSheetParser(sst);
           // 根據(jù) rId# 或 rSheet# 查找sheet
           InputStream sheet2 = r.getSheet("rId"+sheetId);
           sheetIndex++;
           InputSource sheetSource = new InputSource(sheet2);
           parser.parse(sheetSource);
           sheet2.close();
    }
    /**
     * 遍歷工作簿中所有的電子表格
     * @param multipartFile
     * @throws Exception
     */
    public void process(MultipartFile multipartFile) throws Exception {
  //或得文件流
        InputStream in = multipartFile.getInputStream();
        //獲取實(shí)例對(duì)象
          OPCPackage pkg = OPCPackage.open(in);
          XSSFReader r = new XSSFReader(pkg);
           SharedStringsTable sst = r.getSharedStringsTable();
           XMLReader parser = fetchSheetParser(sst);
           Iterator<InputStream> sheets = r.getSheetsData();
           while (sheets.hasNext()) {
                   curRow = 0;
                   sheetIndex++;
                   InputStream sheet = sheets.next();
                  //查看轉(zhuǎn)換的xml原始文件,方便理解后面解析時(shí)的處理,
            // 注意:如果打開(kāi)注釋,下面parse()就讀不到流的內(nèi)容了
             // this.streamOut(in);
                   InputSource sheetSource = new InputSource(sheet);
                  //據(jù)說(shuō)當(dāng)執(zhí)行這個(gè)方法時(shí)  自動(dòng)觸發(fā) startElement(開(kāi)始的元素)    endElement(結(jié)束的元素)
                   parser.parse(sheetSource);
                   sheet.close();
           }
    }
   //讀取流,查看文件內(nèi)容
        public static void streamOut(InputStream in) throws Exception{
            byte[] buf = new byte[1024];
            int len;
            while ((len=in.read(buf))!=-1){
                System.out.write(buf,0,len);
            }
        }

    public XMLReader fetchSheetParser(SharedStringsTable sst)
                   throws SAXException {
           XMLReader parser = XMLReaderFactory
                           .createXMLReader("org.apache.xerces.parsers.SAXParser");
           this.sst = sst;
           parser.setContentHandler(this);
           return parser;
    }
/*
name  Excel轉(zhuǎn)xml后的開(kāi)始標(biāo)簽   這個(gè)方法 可以把參數(shù)都打出來(lái)看看
*/
    public void startElement(String uri, String localName, String name,
                   Attributes attributes) throws SAXException {
         if (name.equals("dimension")){
                dimension = attributes.getValue("ref");
                longest = covertRowIdtoInt(dimension.substring(dimension.indexOf(":")+1) );
            }
           // c => 表示是不是單元格  row=><row>:開(kāi)始處理某一行   isTextTag(name)<v>:單元格值
           if ("c".equals(name)) {
                //當(dāng)前單元格的位置
               String cellId = attributes.getValue("r");
               //空單元判斷,添加空字符到list
                if (lastCellid!=null)
                {
                    int gap = covertRowIdtoInt(cellId)-covertRowIdtoInt(lastCellid);
                    for(int i=0;i<gap-1;i++)
                    {
                          rowlist.add(curCol, "");
                          curCol++;
                    }
                }else{
                    //第一個(gè)單元格可能不是在第一列
                    if (!"A1".equals(cellId))
                    {
                        for(int i=0;i<covertRowIdtoInt(cellId)-1;i++)
                        {
                              rowlist.add(curCol, "");
                              curCol++;
                        }
                    }
                }
                lastCellid = cellId;
            // 如果下一個(gè)元素是 SST 的索引,則將nextIsString標(biāo)記為true
                   //判斷單元格的值是SST 的索引,不能直接characters方法取值
                if (attributes.getValue("t")!=null && attributes.getValue("t").equals("s"))
                {
                    nextIsString = true;
                    cellNull=false;
                }else{
                    nextIsString = false;
                    cellNull=true;
                }
           }
           //當(dāng)元素為t時(shí)
           if("t".equals(name)){
                   isTElement = true;
           } else {
                   isTElement = false;
           }
           // 置空
           lastContents = "";
    }
    public void endElement(String uri, String localName, String name)
                   throws SAXException {
           // 根據(jù)SST的索引值的到單元格的真正要存儲(chǔ)的字符串
           // 這時(shí)characters()方法可能會(huì)被調(diào)用多次
           if (nextIsString) {
               try {
                       int idx = Integer.parseInt(lastContents);
                       lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString().trim();
               } catch (Exception e) {
               }
           }
           //t元素也包含字符串
           if(isTElement){
                   String value = lastContents;
                   value = value.equals("")?" ":value;
                   rowlist.add(curCol, value);
                   curCol++;
                   isTElement = false;
                   // v => 單元格的值,如果單元格是字符串則v標(biāo)簽的值為該字符串在SST中的索引
                   // 將單元格內(nèi)容加入rowlist中,在這之前先去掉字符串前后的空白符
           } else if ("v".equals(name)) {
                   String value = lastContents;
                   value = value.equals("")?" ":value;
                   cellNull=false;
                   rowlist.add(curCol, value);
                   curCol++;
           }
           else if("c".equals(name) && cellNull == true){  
               rowlist.add(curCol, "");  
               curCol++;  
               cellNull = false;  
           }else {
                   //如果標(biāo)簽名稱為 row ,這說(shuō)明已到行尾,調(diào)用 optRows() 方法
                   if (name.equals("row")) {
                          //大于0的判斷主要是篩除表頭信息  這里具體看你想要的信息在哪一行開(kāi)始
                       if(curRow>0){
                           //判斷最后一個(gè)單元格是否在最后,補(bǔ)齊列數(shù)
                            if(covertRowIdtoInt(lastCellid)<longest){
                               for(int i=0;i<longest- covertRowIdtoInt(lastCellid);i++)
                                {
                                 rowlist.add(curCol, "");  
                                 curCol++; 
                                }
                            }
                           //將此行放入一個(gè)大集合
                           excelList.add(rowlist);
                       }
                       rowlist=new ArrayList<String>();
                       curRow++;
                       curCol = 0;
                   }else if(name.equals("worksheet")){
                          //結(jié)束標(biāo)簽為worksheet說(shuō)明工作簿sheet讀取完成
                          //調(diào)用要處理的方法
                       importService.getRows(excelList);
                   }
           }
    }
    public void characters(char[] ch, int start, int length)
                   throws SAXException {
           //得到單元格內(nèi)容的值
           lastContents += new String(ch, start, length);
    }
    /**
     * 列號(hào)轉(zhuǎn)數(shù)字   AB7-->28 第28列
     * @param cellId
     * @return
     */
    public static int covertRowIdtoInt(String cellId){
        int firstDigit = -1;
        for (int c = 0; c < cellId.length(); ++c) {
            if (Character.isDigit(cellId.charAt(c))) {
                firstDigit = c;
                break;
            }
        }
        //AB7-->AB
        //AB是列號(hào), 7是行號(hào)
        String newRowId = cellId.substring(0,firstDigit);
        int num = 0;
        int result = 0;
        int length = newRowId.length();
        for(int i = 0; i < length; i++) {
            //先取最低位,B
            char ch = newRowId.charAt(length - i - 1);
            //B表示的十進(jìn)制2,ascii碼相減,以A的ascii碼為基準(zhǔn),A表示1,B表示2
            num = (int)(ch - 'A' + 1) ;
            //列號(hào)轉(zhuǎn)換相當(dāng)于26進(jìn)制數(shù)轉(zhuǎn)10進(jìn)制
            num *= Math.pow(26, i);
            result += num;
        }
        return result;

    }
}

浪客行1213的簡(jiǎn)書


xhh
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,634評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,653評(píng)論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,063評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,835評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,235評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,459評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,000評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,819評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,004評(píng)論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,257評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,676評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,937評(píng)論 1 288
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,717評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,003評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,121評(píng)論 1 32
  • 前言 在數(shù)據(jù)倉(cāng)庫(kù)中,ETL最基礎(chǔ)的步驟就是從數(shù)據(jù)源抽取所需的數(shù)據(jù),這里所說(shuō)的數(shù)據(jù)源并非僅僅是指數(shù)據(jù)庫(kù),還包括exc...
    kMacro閱讀 1,273評(píng)論 0 3
  • JSPXCMS開(kāi)發(fā)架構(gòu)介紹 V1 – 架構(gòu)概述 基本概述 配置文件目錄 /src/main/resources/...
    Java_Evan閱讀 4,424評(píng)論 0 0
  • # 一、框架概述 # 課程概述 1. laravel 4天(之前TP框架還是很大的區(qū)別)(國(guó)外框架) 2. 在線教...
    關(guān)進(jìn)一閱讀 391評(píng)論 0 0
  • 2018年,最喜歡的男孩結(jié)婚了,畢業(yè)后玩兒的最多的女孩結(jié)婚了,曾經(jīng)料定自己會(huì)孤獨(dú)終老的男人結(jié)婚了,年輕時(shí)的芳心暗...
    一顆牙疼_dabc閱讀 328評(píng)論 0 4