java對文檔的相關(guān)操作

在實際項目的開發(fā)過程中狱掂,有一些需求是涉及到對各種文檔文件的操作伺帘,由于在近期的工作中使用到一些 word 和 *pdf *的操作谤辜,因此在這篇文章中厉亏,我會簡單介紹下 *word *和 pdf 的相關(guān)操作方法垄提。

1伏社、pdf文檔預(yù)覽

word、excel等文檔的預(yù)覽塔淤,如果是免費(fèi)的摘昌,絕大多數(shù)都是基于openoffice去實現(xiàn)的,給大家提供一個參考:文檔預(yù)覽開源服務(wù)
(如果考慮付費(fèi)產(chǎn)品的話高蜂,可以看看:永中office聪黎、office365等)。

這里介紹使用pdf.js來預(yù)覽pdf备恤,pdf.js下載鏈接稿饰,提取碼:ew60,需要將這個pdfjs文件夾放到項目中(我這邊是放在webapp/resources/plugin里面露泊,如下圖)喉镰。

調(diào)用方法:(假設(shè)pdfjs訪問的路徑是$prefix/pdfjs)

需要給預(yù)覽頁面的iframe的src屬性設(shè)置如下:

    "$prefix/pdfjs/web/viewer.html?file=" + encodeURIComponent(url)

上面的url指的是文件的訪問地址(如:http://localhost:8080/file/abc.txt

ps:使用pdfjs預(yù)覽時,插件中默認(rèn)會有下載和打印按鈕惭笑,如果項目中需要對這兩個按鈕設(shè)置操作權(quán)限的話侣姆,則需要在js中去處理。(如果不需要這兩個按鈕沉噩,則只需要在pdfjs/web/viewer.html中找到id="download"捺宗、id="print"、 id="secondaryPrint" 和 id="secondaryDownload"川蒙,分別加上style="display: none;")

js動態(tài)隱藏下載和打印按鈕蚜厉,如下圖:

2、文檔解析-word文檔占位符替換

word占位符替換一般有兩種情況
①替換word段落的占位符(標(biāo)題畜眨、段落等除表格以外的元素)
②替換word表格的占位符
相關(guān)方法如下:

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 替換文檔中的段落和表格占位符
 *
 * @author zhuLong
 * @since 2020/6/5 9:54
 */
public class WordReplaceUtil {

    /**
     * 替換段落中的占位符
     *
     * @param doc    需要替換的文檔
     * @param params 替換的參數(shù)昼牛,key=占位符术瓮,value=實際值
     */
    public static void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            if (!StringUtils.isEmpty(para.getParagraphText())) {
                replaceInPara(para, params);
            }
        }
    }

    /**
     * 替換段落中的占位符
     *
     * @param para
     */
    public static void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
        // 獲取當(dāng)前段落的文本
        String sourceText = para.getParagraphText();
        // 控制變量
        boolean replace = false;
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            if (sourceText.indexOf(key) != -1) {
                Object value = entry.getValue();
                if (value instanceof String) {
                    // 替換文本占位符
                    sourceText = sourceText.replace(key, value.toString());
                    replace = true;
                }
            }
        }
        if (replace) {
            Integer fontSize = null;
            boolean isBold = false;
            // 獲取段落中的行數(shù)
            List<XWPFRun> runList = para.getRuns();
            for (int i = runList.size() - 1; i >= 0; i--) {
                if (runList.get(i).getFontSize() > 0) {
                    fontSize = runList.get(i).getFontSize();
                }
                if (runList.get(i).isBold()) {
                    isBold = runList.get(i).isBold();
                }

                // 刪除之前的行
                para.removeRun(i);
            }
            // 創(chuàng)建一個新的文本并設(shè)置為替換后的值 這樣操作之后之前文本的樣式就沒有了,待改進(jìn)
            XWPFRun run = para.createRun();
            run.setBold(isBold);
            run.setText(sourceText);
            if (fontSize != null) {
                run.setFontSize(fontSize);
            }
        }
    }

    /**
     * 替換表格中的占位符
     *
     * @param doc
     * @param params
     */
    public static void replaceTable(XWPFDocument doc, Map<String, Object> params) {
        // 獲取文檔中所有的表格
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            if (table.getRows().size() > 1) {
                //判斷表格是需要替換還是需要插入贰健,判斷邏輯有${為替換胞四,
                if (matcher(table.getText()).find()) {
                    rows = table.getRows();
                    for (XWPFTableRow row : rows) {
                        cells = row.getTableCells();
                        for (XWPFTableCell cell : cells) {
                            paras = cell.getParagraphs();
                            for (XWPFParagraph para : paras) {
                                replaceInPara(para, params);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 正則匹配字符串
     *
     * @param str
     * @return
     */
    private static Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     * 需要替換的內(nèi)容
     */
    private static Map<String, Object> createParamsMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("${name}", "abc");
        map.put("${sex}", "男");
        return map;
    }

    public static void main(String[] args) throws Exception {
        File mainFile = new File("C:\\Users\\zhulong\\Desktop\\abc.docx");
        InputStream in = new FileInputStream(mainFile);
        OPCPackage srcPackage = OPCPackage.open(in);
        XWPFDocument doc = new XWPFDocument(srcPackage);
        WordReplaceUtil.replaceTable(doc, createParamsMap());
    }
}

3、文檔解析-word文檔添加行數(shù)據(jù)

import cn.hutool.core.util.ArrayUtil;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;

/**
 * word 文檔操作
 *
 * @author zhuLong
 * @since 2020/6/29 9:16
 */
public class WordUtils {
    /**
     * insertRow 在word表格中指定位置插入一行霎烙,復(fù)制指定行樣式
     *
     * @param copyrowIndex 需要復(fù)制的行位置
     * @param newrowIndex  需要新增一行的位置
     */
    public static void insertRow(XWPFTable table, int copyrowIndex, int newrowIndex, String[] datas) {
        // 在表格中指定的位置新增一行
        XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);
        // 獲取需要復(fù)制行對象
        XWPFTableRow copyRow = table.getRow(copyrowIndex);
        //復(fù)制行對象
        targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());
        //或許需要復(fù)制的行的列
        List<XWPFTableCell> copyCells = copyRow.getTableCells();
        //復(fù)制列對象
        XWPFTableCell targetCell = null;
        for (int i = 0; i < copyCells.size(); i++) {
            XWPFTableCell copyCell = copyCells.get(i);
            String a = copyCell.getText();
            targetCell = targetRow.addNewTableCell();
            targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());
            if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
                targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());
                if (copyCell.getParagraphs().get(0).getRuns() != null
                        && copyCell.getParagraphs().get(0).getRuns().size() > 0) {
                    XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();
                    cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold());
                    if (ArrayUtil.isNotEmpty(datas)) {
                        cellR.setText(datas[i]);
                        cellR.setFontSize(10);
                    }
                }
            }
        }

    }

    public static void main(String[] args) throws Exception{
        File mainFile = new File("C:\\Users\\zhulong\\Desktop\\abc.docx");
        InputStream in = new FileInputStream(mainFile);
        OPCPackage srcPackage = OPCPackage.open(in);
        XWPFDocument doc = new XWPFDocument(srcPackage);
        // 動態(tài)插入一行
        List<XWPFTable> tables = doc.getTables();//獲取word中所有的表格
        XWPFTable table = tables.get(0);//獲取第一個表格
        String[] datas = new String[5];
        datas[0] = "a";
        datas[1] = "b";
        datas[2] = "c";
        datas[3] = "d";
        datas[4] = "e";
        WordUtils.insertRow(table, 1, 2, datas);
    }
}

4撬讽、文檔解析-pdf相關(guān)操作

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * pdf相關(guān)操作工具類
 *
 * @author zhuLong
 * @since 2020/6/18 17:03
 */
public class PdfUtil {

    private static final Logger logger = LoggerFactory.getLogger(PdfUtil.class);

    /*
     * 合并pdf文件
     * @param files 要合并文件數(shù)組(絕對路徑如{ "e:\\1.pdf", "e:\\2.pdf" ,
     * "e:\\3.pdf"}),合并的順序按照數(shù)組中的先后順序,如2.pdf合并在1.pdf后悬垃。
     * @param newfile 合并后新產(chǎn)生的文件絕對路徑游昼,如 e:\\temp\\tempNew.pdf,
     * @return boolean 合并成功返回true;否則尝蠕,返回false
     *
     */
    public static boolean mergePdfFiles(String[] files, String newfile) {
        boolean retValue = false;
        Document document = null;
        try {
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));
            document.open();
            for (int i = 0; i < files.length; i++) {
                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
            }
            retValue = true;
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            System.out.println("執(zhí)行結(jié)束");
            if (document != null) {
                document.close();
            }
        }
        return retValue;
    }

    /**
     * pdf轉(zhuǎn)png
     *
     * @param inputStream pdf文件輸入流
     * @author zhuLong
     * @since 2020/6/19 14:17
     */
    public static File pdf2png(InputStream inputStream) {
        try {
            PDDocument doc = PDDocument.load(inputStream);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // 創(chuàng)建臨時文件
                File temp = File.createTempFile("myTempFile", ".png");
                ImageIO.write(image, "png", temp);
                return temp;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * pdf轉(zhuǎn)png
     *
     * @param filePath pdf文件路徑
     * @author zhuLong
     * @since 2020/6/18 23:00
     */
    public static File pdf2png(String filePath) throws FileNotFoundException {
        // 將pdf裝圖片 并且自定義圖片得格式大小
        File file = new File(filePath);
        InputStream inputStream = new FileInputStream(file);
        return pdf2png(inputStream);
    }

    /**
     * pdf轉(zhuǎn)png
     *
     * @param file pdf文件
     * @author zhuLong
     * @since 2020/6/18 23:00
     */
    public static File pdf2png(File file) throws FileNotFoundException {
        // 將pdf裝圖片 并且自定義圖片得格式大小
        InputStream inputStream = new FileInputStream(file);
        return pdf2png(inputStream);
    }

    /**
     * @param imgPath 圖片路徑
     * @param pdf     生成的pdf
     * @author zhuLong
     * @since 2020/6/18 23:00
     */
    public static void image2pdf(String imgPath, File pdf) throws DocumentException, IOException {
        Document document = new Document();
        OutputStream os = new FileOutputStream(pdf);
        PdfWriter.getInstance(document, os);
        document.open();
        createPdf(document, imgPath);
        document.close();
    }

    private static void createPdf(Document document, String imgPath) {
        try {
            Image image = Image.getInstance(imgPath);
            float documentWidth = document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin();
            System.out.println(documentWidth + "");
            float documentHeight = documentWidth / 580 * 850;//重新設(shè)置寬高
            System.out.println(documentHeight + "");
            image.scaleAbsolute(documentWidth, documentHeight);//重新設(shè)置寬高
            document.add(image);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                document.close();
            }
        }
    }

    /**
     * 給pdf上添加水印文本
     *
     * @param contentList x烘豌、y坐標(biāo)及文本的集合
     * @param file        源pdf文件
     * @param fontSize    字體大小
     * @author zhuLong
     * @since 2020/6/19 9:40
     */
    public static File setWatermark(List<Map<String, Object>> contentList, File file, float fontSize) throws FileNotFoundException {
        InputStream in = new FileInputStream(file);
        return setWatermark(contentList, in, fontSize);
    }

    /**
     * 給pdf上添加水印文本
     *
     * @param contentList x、y坐標(biāo)及文本的集合
     * @param inputStream 源pdf文件輸入流
     * @param fontSize    字體大小
     * @author zhuLong
     * @since 2020/6/19 9:40
     */
    public static File setWatermark(List<Map<String, Object>> contentList, InputStream inputStream, float fontSize) {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(inputStream);

            // 創(chuàng)建臨時文件
            File dest = File.createTempFile("pdf", ".pdf");
            stamper = new PdfStamper(reader, new FileOutputStream(dest));
            //不可遮擋文字看彼,只操作第一頁
            PdfContentByte content = stamper.getOverContent(1);
            content.saveState();
            content.fill();
            content.restoreState();
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            //開始寫入文本
            content.beginText();
            //字體大小
            content.setFontAndSize(base, fontSize);
            if (!contentList.isEmpty()) {
                for (Map<String, Object> map : contentList) {
                    //設(shè)置字體的輸出位置
                    int x = Integer.parseInt(map.get("x").toString());
                    int y = Integer.parseInt(map.get("y").toString());
                    content.setTextMatrix(x, y);
                    content.showText(map.get("contentText").toString());
                }
            }
            content.endText();
            return dest;
        } catch (Exception e) {
            logger.error("操作pdf文件異常", e);
        } finally {
            try {
                if (stamper != null) {
                    stamper.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\zhulong\\Desktop\\1.pdf");
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("x", 480);
        map1.put("y", 690);
        map1.put("contentText", "10001");
        list.add(map1);
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("x", 425);
        map2.put("y", 690);
        map2.put("contentText", LocalDateTime.now().getYear());
        list.add(map2);
        File file1 = setWatermark(list, file, 14);
        System.out.println(file1.getAbsolutePath());
    }

}

5廊佩、圖片裁剪拼接

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * 圖片相關(guān)工具類
 *
 * @author zhuLong
 * @since 2020/6/18 23:15
 */
public class ImageUtil {

    /**
     * 裁剪圖片
     *
     * @param imgIn  待裁剪的圖片
     * @param imgOut 裁剪后的圖片
     */
    public static void cutImg(File imgIn, File imgOut, int x, int y, int width, int height) {
        try {
            BufferedImage bufferedImage = ImageIO.read(imgIn);
            BufferedImage back = bufferedImage.getSubimage(x, y, width, height);
            ImageIO.write(back, "png", imgOut);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Java拼接多張圖片
     *
     * @param pics    圖片路徑數(shù)組
     * @param type    圖片類型
     * @param dstFile 目標(biāo)文件
     */
    public static void merge(File[] pics, String type, File dstFile) {

        int len = pics.length;
        if (len < 1) {
            System.out.println("pics len < 1");
        }
        BufferedImage[] images = new BufferedImage[len];
        int[][] ImageArrays = new int[len][];
        for (int i = 0; i < len; i++) {
            try {
                images[i] = ImageIO.read(pics[i]);
            } catch (Exception e) {
                e.printStackTrace();
            }
            int width = images[i].getWidth();
            int height = images[i].getHeight();
            ImageArrays[i] = new int[width * height];// 從圖片中讀取RGB
            ImageArrays[i] = images[i].getRGB(0, 0, width, height,
                    ImageArrays[i], 0, width);
        }

        int dst_height = 0;
        int dst_width = images[0].getWidth();
        for (int i = 0; i < images.length; i++) {
            dst_width = dst_width > images[i].getWidth() ? dst_width
                    : images[i].getWidth();

            dst_height += images[i].getHeight();
        }
        if (dst_height < 1) {
            System.out.println("dst_height < 1");
        }

        // 生成新圖片
        try {
            BufferedImage ImageNew = new BufferedImage(dst_width, dst_height,
                    BufferedImage.TYPE_INT_RGB);
            int height_i = 0;
            for (int i = 0; i < images.length; i++) {
                ImageNew.setRGB(0, height_i, dst_width, images[i].getHeight(),
                        ImageArrays[i], 0, dst_width);
                height_i += images[i].getHeight();
            }
            // 寫圖片
            ImageIO.write(ImageNew, type, dstFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

6、word文檔轉(zhuǎn)換

Free Spire.Doc for Java 是一款免費(fèi)靖榕、專業(yè)的Java Word組件标锄,開發(fā)人員使用它可以輕松地將Word文檔創(chuàng)建、讀取茁计、編輯料皇、轉(zhuǎn)換和打印等功能集成到自己的Java應(yīng)用程序中。作為一款完全獨(dú)立的組件星压,F(xiàn)ree Spire.Doc for Java的運(yùn)行環(huán)境無需安裝Microsoft Office践剂。

Free Spire.Doc for Java能執(zhí)行多種Word文檔處理任務(wù),包括生成娜膘、讀取逊脯、轉(zhuǎn)換和打印Word文檔,插入圖片竣贪,添加頁眉和頁腳军洼,創(chuàng)建表格,添加表單域和郵件合并域贾富,添加書簽歉眷,添加文本和圖片水印,設(shè)置背景顏色和背景圖片颤枪,添加腳注和尾注,添加超鏈接淑际,加密和解密Word文檔畏纲,添加批注扇住,添加形狀等。

友情提示:免費(fèi)版有篇幅限制盗胀。在加載或保存Word 文檔時艘蹋,要求 Word 文檔不超過 500 個段落,25 個表格票灰。同時將 Word 文檔轉(zhuǎn)換為 PDF 和 XPS 等格式時女阀,僅支持轉(zhuǎn)換前三頁。

在這里我們只介紹利用Free Spire.Doc for Java 將word轉(zhuǎn)換為pdf屑迂。
1> pom文件引入依賴

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <url>http://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>

<dependencies>
        ......
        <!-- spire操作word -->
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.doc.free</artifactId>
            <version>2.7.3</version>
        </dependency>
</dependencies>

2>方法調(diào)用

public static void main(String[] args) {
        //加載word示例文檔
        Document document = new Document();
        document.loadFromFile("C:\\Users\\zhulong\\Desktop\\test.docx");
        //保存結(jié)果文件
        document.saveToFile("C:\\Users\\zhulong\\Desktop\\test.pdf", FileFormat.PDF); 
}

當(dāng)然浸策,excel轉(zhuǎn)pdf也是支持的,可以使用Free Spire.XLS for Java惹盼,免費(fèi)版有一定的限制庸汗,官網(wǎng)地址:https://www.e-iceblue.cn/Introduce/Free-Spire-XLS-JAVA.html

另外,也可以考慮使用openoffice組件進(jìn)行文檔的轉(zhuǎn)換手报。

7蚯舱、文檔轉(zhuǎn)換后字體亂碼問題

一般文檔轉(zhuǎn)換經(jīng)常會出現(xiàn)一種現(xiàn)象:本地(windows)上測試沒問題,但是到了服務(wù)器(linux)上測試就出現(xiàn)中文亂碼等問題掩蛤,這種現(xiàn)象基本都是因為linux服務(wù)器上沒有相關(guān)字體導(dǎo)致的枉昏。

解決方法:

  • 第一步:在linux服務(wù)器上安裝中文字體庫
    安裝參考鏈接:linux安裝中文字體庫
    安裝成功后,記得把你的應(yīng)用服務(wù)重啟再試一下揍鸟,如果還是不行兄裂,說明你的源文檔中的相關(guān)字體在linux服務(wù)器上找不到,進(jìn)行第二步蜈亩。
  • 第二步:定位你的文檔中亂碼那塊的字體名稱懦窘,然后到 C:\Windows\Fonts 這個目錄下(windows系統(tǒng))找到對應(yīng)字體文件,復(fù)制到linux服務(wù)器上的/usr/share/fonts文件夾里面稚配,然后依次執(zhí)行如下命令:
mkfontscale //字體擴(kuò)展
mkfontdir   //新增字體目錄
fc-cache    //刷新緩存

注意:執(zhí)行完之后畅涂,依然需要重啟應(yīng)用服務(wù)。

一般由于字體問題導(dǎo)致的亂碼通過這種方法基本都可以得到解決道川。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末午衰,一起剝皮案震驚了整個濱河市呢燥,隨后出現(xiàn)的幾起案子球榆,更是在濱河造成了極大的恐慌,老刑警劉巖蕉饼,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尊流,死亡現(xiàn)場離奇詭異帅戒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)崖技,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門逻住,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钟哥,“玉大人,你說我怎么就攤上這事瞎访∧宸。” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵扒秸,是天一觀的道長播演。 經(jīng)常有香客問我,道長伴奥,這世上最難降的妖魔是什么写烤? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮渔伯,結(jié)果婚禮上顶霞,老公的妹妹穿的比我還像新娘。我一直安慰自己锣吼,他們只是感情好选浑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玄叠,像睡著了一般古徒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上读恃,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天隧膘,我揣著相機(jī)與錄音,去河邊找鬼寺惫。 笑死疹吃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的西雀。 我是一名探鬼主播萨驶,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼艇肴!你這毒婦竟也來了腔呜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤再悼,失蹤者是張志新(化名)和其女友劉穎核畴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冲九,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谤草,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咖刃。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡泳炉,死狀恐怖憾筏,靈堂內(nèi)的尸體忽然破棺而出嚎杨,到底是詐尸還是另有隱情,我是刑警寧澤氧腰,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布枫浙,位于F島的核電站,受9級特大地震影響古拴,放射性物質(zhì)發(fā)生泄漏箩帚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一黄痪、第九天 我趴在偏房一處隱蔽的房頂上張望紧帕。 院中可真熱鬧,春花似錦桅打、人聲如沸是嗜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹅搪。三九已至,卻和暖如春遭铺,著一層夾襖步出監(jiān)牢的瞬間丽柿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工魂挂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留甫题,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓涂召,卻偏偏與公主長得像坠非,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子芹扭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349