iOS 數(shù)據(jù)導(dǎo)出為PDF(生成PDF文件)

需求:根據(jù)App中的數(shù)據(jù)來(lái)生成PDF文件竞膳,盡量越小越好航瞭,不要爆內(nèi)存。

找了很多資料坦辟,先用第一種方式實(shí)現(xiàn)了刊侯,然后發(fā)現(xiàn)生成的PDF文件過大,又找了新的方案實(shí)現(xiàn)锉走,在此記錄一下滨彻。

兩種實(shí)現(xiàn)方式說明:
一、自己創(chuàng)建View挪蹭,按照OC的方式畫頁(yè)面亭饵,畫完之后將一頁(yè)頁(yè)View繪制到PDF文件中

優(yōu)點(diǎn):在View中畫簡(jiǎn)單易懂,轉(zhuǎn)成PDF的方式也簡(jiǎn)單
缺點(diǎn):由于是將每一頁(yè)的整個(gè)View給當(dāng)成圖片繪制到PDF中梁厉,保存的PDF內(nèi)都是圖片辜羊,無(wú)法修改文字,且词顾!PDF文檔非常的大八秃!

二、從頭到尾都使用手繪的方式去生成PDF肉盹,將各個(gè)控件自己畫出來(lái)

優(yōu)點(diǎn):速度很快昔驱,生成的PDF文件足夠的小,例:測(cè)試我的五萬(wàn)條數(shù)據(jù)上忍,基本都是純文本的骤肛,共計(jì)3000多頁(yè),需要15s左右窍蓝,文件大小只有4M萌衬,如果使用第一種方式,五千條數(shù)據(jù)都300M了它抱,差距有點(diǎn)大秕豫。
缺點(diǎn):整個(gè)繪制過程比較麻煩,如果是統(tǒng)一樣式的列表,還可以用for循環(huán)混移,如果特殊樣式太多祠墅,全都要自己寫。例:一行文本數(shù)據(jù)顯示一行歌径,最后超出的部分省略號(hào)表示毁嗦,這個(gè)省略號(hào)都要自己寫,并且要定義樣式與前邊的文字相同回铛!
要非常非常注意狗准,在繪制PDF過程中,你創(chuàng)建的對(duì)象茵肃,都要釋放掉腔长。不然幾百頁(yè)的PDF在for循環(huán)的過程中會(huì)產(chǎn)生非常大的內(nèi)存占用,點(diǎn)幾次生成PDF之后验残,App直接就因?yàn)楸瑑?nèi)存崩掉了捞附。
具體如何釋放,請(qǐng)看第二種方式中的代碼提示

實(shí)現(xiàn)過程:
// 首先定義了頁(yè)面的一些常用數(shù)據(jù)
static const CGFloat A4Width = 595.f; // PDF頁(yè)面的寬
static const CGFloat A4Height = 842.f; // PDF頁(yè)面的高
static const CGFloat topSpace = 40.f; // 頁(yè)眉和頁(yè)腳的高度
static const CGFloat bottomSpace = 50.f; // 頁(yè)眉和頁(yè)腳的高度 // 下邊距需要留出來(lái)一定間距您没,不然會(huì)很擠
static const CGFloat leftRightSpace = 20.f; // 左右間距的寬度
static const CGFloat contentHeight = A4Height – topSpace – bottomSpace; // 除去頁(yè)眉頁(yè)腳之后的內(nèi)容高度
static const CGFloat contentWidth = A4Width – leftRightSpace * 2; // 內(nèi)容寬度
static const CGFloat targetSpace = 10.f; // 每個(gè)詞條View的間距
static const CGFloat targetHeight = 14.f; // 詞條信息每一行的高度
static const CGFloat favoritesHeight = 80.f; // 收藏夾的高度鸟召,也是收藏夾圖片的高度
第一種實(shí)現(xiàn)方式:
/**
 通過在View上畫好頁(yè)面,然后繪制到PDF頁(yè)面中實(shí)現(xiàn)轉(zhuǎn)PDF, 生成的PDF文件因?yàn)閮?nèi)部全是圖片氨鹏,文件非常大
 dataInfo:MOJi數(shù)據(jù)
 pdfName: 保存的PDF名稱欧募,需要注意帶上.pdf后綴!
 */
+ (void)createPDFViewWithDataInfo:(MOJiPDFDataInfo *)dataInfo PDFName:(NSString *)pdfName {
    
    NSMutableArray *viewArr = [[NSMutableArray alloc] init]; // 存放PDF的頁(yè)面的數(shù)組
    
    // 存放所有詞條信息View的數(shù)組
    NSMutableArray *targetViewArr = [[NSMutableArray alloc] init];
    NSMutableArray *targetHeightArr = [[NSMutableArray alloc] init]; // 存放每一個(gè)詞條的所占高度
    CGFloat allTargetHeight = headerView.height + targetSpace;
    for (int i = 0; i < dataInfo.targetArr.count; i++) {
        MOJiPDFTarget *targetInfo = [dataInfo.targetArr objectAtIndex:i];

        UIView *targetView = [[UIView alloc] initWithFrame:CGRectZero];

        CGFloat height = 100.f; // 這個(gè)高度需要自己計(jì)算仆抵,此處只是示例
        
        targetView.frame = CGRectMake(0, 0, contentWidth, height);
        [targetViewArr addObject:targetView];
        [targetHeightArr addObject:@(height + targetSpace)];
        
        allTargetHeight = allTargetHeight + height + targetSpace;
    }
    
    // 補(bǔ)充說明跟继,其實(shí)這里的頁(yè)碼計(jì)算方式是不太正確的,你需要根據(jù)自己的需求來(lái)計(jì)算
    // 計(jì)算總共需要多少頁(yè)P(yáng)DF
    NSInteger allPageCount = ((int)allTargetHeight % (int)contentHeight) > 0 ? (allTargetHeight / contentHeight + 1) : (allTargetHeight / contentHeight);
    
    
    int t = 0; // targetViewArr的計(jì)數(shù)放這里是為了不在PDF頁(yè)碼循環(huán)時(shí)重置
    for (int i = 0; i < allPageCount; i++) {
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, A4Width, A4Height)];
        
        // 頁(yè)眉標(biāo)題
        
        // 頁(yè)碼
        
        // 頁(yè)腳
        
        CGFloat topFrom = topSpace;
        
        for (; t < targetViewArr.count; t++) {
            if (t == targetArr.count) break;

            // 剩余距離不夠的情況下肢础,翻頁(yè)
            CGFloat th = [[targetHeightArr objectAtIndex:t] floatValue];
            if ((topFrom + th - targetSpace) > (A4Height - bottomSpace)) break;
            
            UIView *targetView  = [targetViewArr objectAtIndex:t];
            CGFloat targetH     = targetView.height;
            
            targetView.top      = topFrom;
            targetView.left     = leftRightSpace;
            [view addSubview:targetView];
            topFrom = topFrom + targetH + targetSpace;
        }
        
        [viewArr addObject:view];
    }
    
    // 用生成的頁(yè)面生成PDF
    [MOJiPDF createPDFWithViewArr:[viewArr copy] PDFName:pdfName progress:PDFCreateProgressBlock];
}


+ (void)createPDFWithViewArr:(NSArray <UIView *>*)viewArr PDFName:(NSString *)pdfName progress:(nullable void(^)(NSString *progress))PDFCreateProgressBlock {
    
    if (viewArr.count == 0 || pdfName.length == 0) return;
    
    NSMutableData *pdfData = [NSMutableData data];
    
    // 文檔信息 可設(shè)置為nil
    CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(nil, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);

    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("PDF Content Title"));
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("PDF Author"));
    
    // 設(shè)置PDF文件每頁(yè)的尺寸
    CGRect pageRect =  CGRectMake(0, 0, A4Width, A4Height);
    // PDF繪制尺寸,設(shè)置為CGRectZero則使用默認(rèn)值612*912
    UIGraphicsBeginPDFContextToData(pdfData, pageRect, nil);
    
    for (int i = 0; i < viewArr.count; i++) {
        UIView *pageView = [viewArr objectAtIndex:i];
        // PDF文檔是分頁(yè)的碌廓,開啟一頁(yè)文檔開始繪制
        UIGraphicsBeginPDFPage();
        // 獲取當(dāng)前的上下文
        CGContextRef pdfContext = UIGraphicsGetCurrentContext();
        [pageView.layer renderInContext:pdfContext];
    }
    UIGraphicsEndPDFContext();
    
    NSArray *documentDirectories        = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory         = [documentDirectories objectAtIndex:0];
    NSString *documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:pdfName];
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}
第二種實(shí)現(xiàn)方式:
/// 完全手動(dòng)的畫出PDF
/// @param dataInfo 需要傳入的dataInfo
/// @param pdfName PDF名字传轰,且需要帶.pdf的后綴
+ (void)toDrawPDFWithDataInfo:(MOJiPDFDataInfo *)dataInfo pdfName:(nullable NSString *)pdfName  {
    
    NSArray *targetArr              = dataInfo.targetArr;
    NSMutableArray *targetHeightArr = [[NSMutableArray alloc] init]; // 存放每一個(gè)詞條的所占高度

    NSInteger allPageCount = 1;
    for (int i = 0; i < targetArr.count; i++) {
        
        // 在這里寫代碼,計(jì)算出總共需要的頁(yè)碼數(shù)谷婆,以及每一個(gè)詞條的高度放入targetHeightArr數(shù)組中
         
    }

    // 1.創(chuàng)建media box
    CGFloat myPageWidth     = A4Width;
    CGFloat myPageHeight    = A4Height;
    CGRect mediaBox         = CGRectMake (0, 0, myPageWidth, myPageHeight);

    // 2.設(shè)置pdf文檔存儲(chǔ)的路徑
    NSArray *paths               = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = paths[0];
    filePath                     = [documentsDirectory stringByAppendingFormat:@"/%@", pdfName];
    const char *cfilePath        = [filePath UTF8String];
    CFStringRef pathRef          = CFStringCreateWithCString(NULL, cfilePath, kCFStringEncodingUTF8);
//    NSLog(@"filePath = %@", filePath);

    // 3.設(shè)置當(dāng)前pdf頁(yè)面的屬性
    CFStringRef myKeys[3];
    CFTypeRef myValues[3];
    myKeys[0]   = kCGPDFContextMediaBox;
    myValues[0] = (CFTypeRef) CFDataCreate(NULL,(const UInt8 *)&mediaBox, sizeof (CGRect));
    myKeys[1]   = kCGPDFContextTitle;
    myValues[1] = CFSTR("我的PDF");
    myKeys[2]   = kCGPDFContextCreator;
    myValues[2] = CFSTR("PDF作者");

    // 4.獲取pdf繪圖上下文
    CGContextRef myPDFContext     = MyPDFContextCreate (&mediaBox, pathRef);

    // ————特別注意慨蛙,字體樣式大小和顏色要這樣設(shè)置,不然無(wú)法釋放——————
    // 設(shè)置字體樣式
    CTFontRef ctFontTitleMedium   = CTFontCreateWithName(CFSTR("PingFangSC-Medium"), 12.0, NULL);
    // 設(shè)置字體顏色 
    CGFloat cmykValue[] = {0.239, 0.270, 0.298, 1};      
    CGColorRef ctColorBlack = CGColorCreate(CGColorSpaceCreateDeviceRGB(), cmykValue);


    int t = 0; // target的計(jì)數(shù)放這里是為了不在PDF頁(yè)碼循環(huán)時(shí)重置
    for (int i = 0; i < allPageCount; i++) {
        if (t == targetArr.count) break;
        
        // 5.開始描繪每一頁(yè)的頁(yè)面
        CFDictionaryRef pageDictionary = CFDictionaryCreate(NULL, (const void **) myKeys, (const void **) myValues, 3,
                                                            &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
        CGPDFContextBeginPage(myPDFContext, pageDictionary);
        
        // 默認(rèn)的原點(diǎn)在左下角纪挎,每一頁(yè)都需要轉(zhuǎn)換坐標(biāo)系的操作!!!!!

        /* 添加頁(yè)腳 */
        CGFloat widthFotter = [MOJiPDF getStringWidthWithFontSize:[UIFont systemFontOfSize:10.f] height:14.f string:@"這是頁(yè)腳"];
        CGRect rectFooter   = CGRectMake(A4Width - 10.f - widthFotter, 10.f, widthFotter, targetHeight);
        [MOJiPDF drawTextWithText:@"這是頁(yè)腳" color:ctColorBlack font:ctFontTargetRegular alignMent:kCTTextAlignmentRight rect:rectFooter maxWidth:contentWidth contextRef:myPDFContext];
        
        CGFloat topFrom = topSpace;
        for (; t < targetArr.count; t++) {
            
            // 剩余距離不夠的情況下期贫,翻頁(yè)
            CGFloat th = [[targetHeightArr objectAtIndex:t] floatValue];
            if ((topFrom + th - targetSpace) > (A4Height - bottomSpace)) break;
            
            MOJiPDFTarget *targetInfo   = [targetArr objectAtIndex:t];

            if (i == 0) {
                topFrom = topSpace + favoritesHeight + targetSpace;
            
                UIImage *iconImg    = [MOJiPDF roundCorners:dataInfo.coverImg size:CGSizeMake(favoritesHeight, favoritesHeight) radius:8.f];
                CGRect iconRect     = [MOJiPDF getFinallyRectWithOriginalRect:CGRectMake(leftRightSpace, 40, favoritesHeight, favoritesHeight)];
                CGContextDrawImage(myPDFContext, iconRect, iconImg.CGImage);
                iconImg = nil;
            }
            
            CGFloat widthTargetTitle    = [MOJiPDF getStringWidthWithFontSize:[UIFont systemFontOfSize:10.f] height:14.f string:targetInfo.title];
            CGRect rectTargetTitle      = [MOJiPDF getFinallyRectWithOriginalRect:CGRectMake(leftRightSpace, topFrom, widthTargetTitle, targetHeight)];
            [MOJiPDF drawTextWithText:targetInfo.title color:ctColorBlack font:ctFontTargetMedium alignMent:kCTTextAlignmentLeft rect:rectTargetTitle maxWidth:contentWidth contextRef:myPDFContext];
            topFrom = topFrom + targetHeight;
        }
        
        CGPDFContextEndPage(myPDFContext);
        CFRelease(pageDictionary);
    }

    // 6.釋放創(chuàng)建的對(duì)象
    CFRelease(ctColorBlack);
    CFRelease(ctFontTitleMedium);
    
    CGContextRelease(myPDFContext);
    CFRelease(myValues[0]);
    CFRelease(myValues[1]);
    CFRelease(myValues[2]);
    CFRelease(myKeys[0]);
    CFRelease(myKeys[1]);
    CFRelease(myKeys[2]);
    CFRelease(pathRef);
}
以上是主要的代碼,以下是需要用到的幾個(gè)函數(shù)
/*
 * 獲取pdf繪圖上下文
 * inMediaBox指定pdf頁(yè)面大小
 * path指定pdf文件保存的路徑
 */
CGContextRef MyPDFContextCreate (const CGRect *inMediaBox, CFStringRef path)
{
    CGContextRef myOutContext = NULL;
    CFURLRef url;
    CGDataConsumerRef dataConsumer;
    
    url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, false);
    
    if (url != NULL)
    {
        dataConsumer = CGDataConsumerCreateWithURL(url);
        if (dataConsumer != NULL)
        {
            myOutContext = CGPDFContextCreate (dataConsumer, inMediaBox, NULL);
            CGDataConsumerRelease (dataConsumer);
        }
        CFRelease(url);
    }
    return myOutContext;
}


/**
 繪制文字的方式
 text: 需要繪制的文字
 color:文字顏色
 font:文字字體及大小
 alignment:文字對(duì)齊方式 (注:這個(gè)參數(shù)在原先的寫法中沒有生效异袄,不知道為什么通砍,暫時(shí)不用管它)
 rect:文字所在范圍
 maxWidth:最大顯示寬度,大于此,先截取然后顯示省略
 contextRef:上下文
 */
+ (void)drawTextWithText:(NSString *)text color:(CGColorRef)color font:(CTFontRef)font alignMent:(CTTextAlignment)alignment rect:(CGRect)rect maxWidth:(CGFloat)maxWidth contextRef:(CGContextRef)contextRef {
    
    CFStringRef keys[]      = {kCTFontAttributeName, kCTForegroundColorAttributeName};
    CFTypeRef values[]      = {font, color};
    CFDictionaryRef attr    = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    
    CFAttributedStringRef attrString   = CFAttributedStringCreate(NULL, (__bridge CFStringRef)text, attr);
    CTLineRef line          = CTLineCreateWithAttributedString(attrString);
    
    NSString *dotString     = @"\u2026";
    CFAttributedStringRef dotStringRef = CFAttributedStringCreate(NULL, (__bridge CFStringRef)dotString, attr);
    CTLineRef token         = CTLineCreateWithAttributedString(dotStringRef);
    
    /** 將現(xiàn)有 CTLineRef 截?cái)嗖⒎祷匾粋€(gè)新的對(duì)象
     * width 截?cái)鄬挾龋喝绻袑挻笥诮財(cái)鄬挾确馑铮瑒t該行將被截?cái)?     * truncationType 截?cái)囝愋?     * truncationToken 截?cái)嘤玫奶畛浞?hào)迹冤,通常是省略號(hào) ... ,為Null時(shí)則只截?cái)嗷⒓桑蛔鎏畛?     *                        該填充符號(hào)的寬度必須小于截?cái)鄬挾扰葆悖駝t該函數(shù)返回 NULL;
     */
    CTLineRef newline = CTLineCreateTruncatedLine(line, maxWidth, kCTLineTruncationEnd, token);
    
    CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);
    CGContextSetTextPosition(contextRef, rect.origin.x, rect.origin.y);
    CTLineDraw(newline, contextRef);
    
    CFRelease(newline);
    CFRelease(token);
    CFRelease(line);
    CFRelease(dotStringRef);
    CFRelease(attrString);
    CFRelease(attr);
    
    CFRelease(keys[0]);
    CFRelease(keys[1]);
}


// 獲取字符串寬度
+ (CGFloat)getStringWidthWithFontSize:(UIFont *)sizeFont height:(CGFloat)height string:(NSString *)string {
    
    CGRect rect = [string boundingRectWithSize:CGSizeMake(MAXFLOAT, height) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:sizeFont} context:nil];
    return rect.size.width;
}


// 根據(jù)正確的坐標(biāo)系 轉(zhuǎn)換為在PDF畫布上的坐標(biāo)系
+ (CGRect)getFinallyRectWithOriginalRect:(CGRect)originalRect {
    
    CGFloat y = A4Height - originalRect.origin.y - originalRect.size.height;
    return CGRectMake(originalRect.origin.x, y, originalRect.size.width, originalRect.size.height);
}


/**
 給UIImage添加圓角
 img: 需要處理的UIImage
 size:UIImage真實(shí)顯示時(shí)候的size
 radius:UIImage真實(shí)顯示時(shí)候的圓角大小
 */
+ (UIImage *)roundCorners:(UIImage*)img size:(CGSize)size radius:(CGFloat)radius {
    
    int w = img.size.width;
    int h = img.size.height;
    CGFloat modulus = w / size.width; // 本身畫圖膜蠢,是根據(jù)img的原始尺寸來(lái)的堪藐,跟要展示的尺寸會(huì)不同,需要自己計(jì)算在原尺寸上的圓角大小
   
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    /**
     CGContextRef CGBitmapContextCreate (

        void *data,                 指向要渲染的繪制內(nèi)存的地址挑围。這個(gè)內(nèi)存塊的大小至少是(bytesPerRow*height)個(gè)字節(jié)
        size_t width,               bitmap的寬度,單位為像素
        size_t height,              bitmap的高度,單位為像素
        size_t bitsPerComponent,    內(nèi)存中像素的每個(gè)組件的位數(shù).例如礁竞,對(duì)于32位像素格式和RGB 顏色空間,你應(yīng)該將這個(gè)值設(shè)為8.
        size_t bytesPerRow,         bitmap的每一行在內(nèi)存所占的比特?cái)?shù)
        CGColorSpaceRef colorspace, bitmap上下文使用的顏色空間贪惹。
        CGBitmapInfo bitmapInfo     指定bitmap是否包含alpha通道苏章,像素中alpha通道的相對(duì)位置,像素組件是整形還是浮點(diǎn)型等信息的字符串奏瞬。
     ); */
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 8 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
   
    CGContextBeginPath(context);
    addRoundedRectToPath(context, CGRectMake(0, 0, w, h), radius * modulus, radius * modulus);
    CGContextClosePath(context);
    CGContextClip(context);
   
    CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
   
    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    UIImage * image = [UIImage imageWithCGImage:imageMasked];
    CGImageRelease(imageMasked);
   
    return image;
}


//這是被調(diào)用的靜態(tài)方法枫绅,繪制圓角用
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
                                float ovalWidth,float ovalHeight)
{
   float fw, fh;
   if (ovalWidth == 0 || ovalHeight == 0) {
       CGContextAddRect(context, rect);
       return;
   }
   
   CGContextSaveGState(context);
   CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
   CGContextScaleCTM (context, ovalWidth, ovalHeight);
   fw = CGRectGetWidth (rect) / ovalWidth;
   fh = CGRectGetHeight (rect) / ovalHeight;
   CGContextMoveToPoint(context, fw, fh/2);
   CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
   CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
   CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
   CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
   CGContextClosePath(context);
   CGContextRestoreGState(context);
}

上邊的代碼中可以看到,幾乎所有的CFXXXRef和一些CG類型的數(shù)據(jù)硼端,你創(chuàng)建或者持有的并淋,就必須要釋放掉!不然在大量數(shù)據(jù)的情況下珍昨,內(nèi)存占用非常的嚴(yán)重县耽。

以上基本就是我自己的Demo了,只是去掉了數(shù)據(jù)部分镣典,你們可以直接復(fù)制粘貼然后填充一下數(shù)據(jù)兔毙,差不多就可以運(yùn)行查看效果了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兄春,一起剝皮案震驚了整個(gè)濱河市澎剥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赶舆,老刑警劉巖哑姚,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芜茵,居然都是意外死亡叙量,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門九串,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)绞佩,“玉大人,你說我怎么就攤上這事≌髁叮” “怎么了析既?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谆奥。 經(jīng)常有香客問我眼坏,道長(zhǎng),這世上最難降的妖魔是什么酸些? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任宰译,我火速辦了婚禮,結(jié)果婚禮上魄懂,老公的妹妹穿的比我還像新娘沿侈。我一直安慰自己,他們只是感情好市栗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布缀拭。 她就那樣靜靜地躺著,像睡著了一般填帽。 火紅的嫁衣襯著肌膚如雪蛛淋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天篡腌,我揣著相機(jī)與錄音褐荷,去河邊找鬼。 笑死嘹悼,一個(gè)胖子當(dāng)著我的面吹牛叛甫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杨伙,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼其监,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了限匣?” 一聲冷哼從身側(cè)響起抖苦,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膛腐,沒想到半個(gè)月后睛约,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鼎俘,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哲身,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贸伐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勘天。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脯丝,到底是詐尸還是另有隱情商膊,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布宠进,位于F島的核電站晕拆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏材蹬。R本人自食惡果不足惜实幕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堤器。 院中可真熱鬧昆庇,春花似錦、人聲如沸闸溃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辉川。三九已至表蝙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間员串,已是汗流浹背勇哗。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寸齐,地道東北人欲诺。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像渺鹦,于是被迫代替她去往敵國(guó)和親扰法。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354