Markdown image 替换为 html标签

使用Typora可以实现公式的预览,图片自动上传到服务器,但图片是markdown语法,这里实现从Markdown 转化为 Html的 img标签

public static function imageReplace($content)
{

	$pattern = ['/!\[img\]\((.*)\)/U','/<p>\s*<\/p>/U'];

	$replacement = ['<img src="\\1" \/>','']; 

	return preg_replace($pattern, $replacement, $content);

}

实现键盘相关操作

想要实现在写作时作用Enter来提交,作用Ctrl+S保存

    document.onkeydown=keyDownSearch;
   
    function keyDownSearch(e) { 
        // 兼容FF和IE和Opera 
        var theEvent = e || window.event; 
        var code = theEvent.keyCode || theEvent.which || theEvent.charCode; 
        if (code == 13) {  
            $("#todo-btn").trigger('click');
            return false; 
        } 
        return true; 
    }

解决动态ajax/pjax加载mathjax不生效问题

<!DOCTYPE html>
<html>
<head>
<title>MathJax TeX Test Page</title>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
<script type="text/javascript" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
</head>
<body>
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</body>
</html>

只要引入mathjax的js地址,配置config,就能自动识别文章中的数学公式写法。显示效果如下:

正常情况下使用,是可以实现显示数学公式的,但是如果你的页面使用了动态加载,即ajax或pjax的情况下,mathjax就不能顺利的渲染出数学公式了。

咳咳,解决动态适配的事情也不是一次两次了,添加事件可以用jquery的on方法委托。在动态调用后执行可以在$.ajax的success方法后执行相关业务逻辑。 pjax则在complete或end后执行相关业务逻辑代码。这里我拿pjax做演示,代码类似下面:

$(document).pjax('a[target!=_top]', '#page', {
    fragment: '#page',
    timeout: 8000,
}).on('pjax:send', function () {
    do something
}).on('pjax:complete', function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML", function() {
        MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
    });
});

想法是在pjax加载complete之后加载mathjax的js依赖,在配置config,因为之前正常使用也是这样的。但是很遗憾,还是没有正常显示。

后来锲而不舍的找到了MathJax.Hub.Typeset()这个方法,结合Queue方法就能实现(不要问我为啥是中文文档,谷歌翻译了解下)

....
.on('pjax:complete', function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML", function() {
        MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
        // entry-content是文章页的内容div的class
        var math = document.getElementsByClassName("entry-content")[0];
        MathJax.Hub.Queue(["Typeset",MathJax.Hub,math]);
    });
});

Katex使用记录

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" integrity="sha384-R4558gYOUz8mP9YWpZJjofhk+zx0AS11p36HnD2ZKj/6JR5z27gSSULCNHIRReVs" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js" integrity="sha384-z1fJDqw8ZApjGO3/unPWUPsIymfsJmyrDVWC8Tv/a1HeOtGmkwNd/7xUS0Xcnvsx" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.getElementById('test'), {
          // customised options
          // • auto-render specific keys, e.g.:
          delimiters: [
              {left: '$$', right: '$$', display: true},
              {left: '$', right: '$', display: false},
              {left: '\\(', right: '\\)', display: false},
              {left: '\\[', right: '\\]', display: true}
          ],
          // • rendering keys, e.g.:
          throwOnError : false
        });
    });
</script>

以上代码可以实现公式的渲染,但不能在Ajax加载时渲染,在使用Ajax加载时去除DOMContentLoaded监听即可

清除指定Html标签

/**
 * 删除指定标签
 * @param array  $tags    删除的标签
 * @param string $str     html字符串
 * @param bool   $type    是否保留标签的内容
 * @return mixed
 * @usage
 *  $str = 'Hello</p><p><img src="http://www.baidu.com" /></b><Video>';
 *
 *      // echo strip_tags($str, '<img');
 *      echo $this->stripHtmlTags(array('b','p'),$str,true);
 */
public static function stripHtmlTags($str,$tags=['p','b'], $content=true)
{
    $html = [];
    if($content){
        foreach ($tags as $tag) {
            $html[] = "/(<(?:\/" .$tag. "|" .$tag. ")[^>]*>)/is";
        }
    }else{
        foreach ($tags as $tag) {
            $html[] = '/<' .$tag. '.*?>[\s|\S]*?<\/' .$tag. '>/is';
            $html[] = '/<' .$tag. '.*?>/is';
        }
    }
    $data = preg_replace($html, '', $str);
    return $data;
}

关于上一页与下一页实现细节

我想要把题库设计一下翻页功能,Mysql语句也很简单,在本地测试一点问题都没有,但是一放到服务器上便提示内存资源耗竭,最后在查看了一些资料后,在后面加了一个limit 1,如此便跑得飞快:

实现代码:

    public static function PrevQuestion($id,$uid=null,$testpaper=null)
    {
        $query = Question::find()->where(['<','id',$id]);

        if($uid)
        {
            $query->andWhere(['author'=>$uid]);
        }

        if($paper)
        {
            $query->LeftJoin('sq_testpaperinfo t','t.paper_id='.$paper_id);
        }

        $query->orderBy('id DESC');

        $query->limit(1);

        return $query->one();
    }

    public static function NextQuestion($id,$uid=null,$testpaper=null)
    {
        $query = Question::find()->where(['>','id',$id]);

        if($uid)
        {
            $query->andWhere(['author'=>$uid]);
        }

        if($paper)
        {
            $query->LeftJoin('sq_testpaperinfo t','t.paper_id='.$paper_id);
        }

        $query->orderBy('id DESC');
        $query->limit(1);

        return $query->one();
    }

下面是参考内容:

/**
* 获取当前记录的上一条记录
* @param seq
* @return
*/
@Select("select title, random_code from tb_blog where seq < ${seq} order by seq desc limit 1 ")
public Map<String,Object> getPreviousBlog(@Param("seq") long seq);

/**
* 获取当前记录的下一条记录
* @param seq
* @return
*/
@Select("select title, random_code from tb_blog where seq > ${seq} order by seq asc limit 1 ")
public Map<String,Object> getPostBlog(@Param("seq") long seq);

seq 是自增序列,random_code是id,title是博客标题。

seq不是主键,要使seq自增,先添加seq字段或建表时创建,再将seq添加unique索引,再使seq auto_increment,因为自增长列必须先是unique key或primary key。

php实现office文档转成pdf预览方法

$filetype = array(".docx",".doc",".xlsx",".xls",".pptx",".ppt",".jpg",".png",".pdf"); //文件类型
$tempFile = "/uploads/".$log["attachment"];                 //$log["attachment"]为文件地址;
$url = str_replace($filetype,"",$tempFile).".pdf";             //替换文件后缀
//header('Location: '.$url);
//die();
$tempFile = "/tmp/".basename($log["attachment"]);             //临时文件地址
copy("www.xxx.com/".$log["attachment"],$tempFile);             //移动文件
exec("unoconv -f pdf ".$tempFile);                           //文件转pdf
$pdf = str_replace($filetype,"",$tempFile).".pdf";           
header("Content-type:application/pdf");
// 文件将被称为 downloaded.pdf
//header("Content-Disposition:attachment;filename=downloaded.pdf");
// PDF 源在 original.pdf 中
readfile($pdf);
//$url = "/uploads/".$log["attachment"];
die();

原文链接:https://blog.csdn.net/leesin2011/article/details/53317362

PHP读取word文档里的文字及图片,并保存

一、composer安装phpWord

composer require phpoffice/phpword

传送门:https://packagist.org/packages/phpoffice/phpword

二、phpWord 读取 docx 文档(注意是docx格式,doc格式不行)

如果你的文件是doc格式,直接另存为一个docx就行了;如果你的doc文档较多,可以下一个批量转换工具:http://www.batchwork.com/en/doc2doc/download.htm

如果你还没配置自动加载,则先配置一下:

require ‘./vendor/autoload.php’;

加载文档:

$dir = str_replace('\', '/', DIR) . '/';
$source = $dir . 'test.docx';
$phpWord = \PhpOffice\PhpWord\IOFactory::load($source);

三、关键点

1)对齐方式:PhpOffice\PhpWord\Style\Paragraph -> getAlignment()

2)字体名称:\PhpOffice\PhpWord\Style\Font -> getName()

3)字体大小:\PhpOffice\PhpWord\Style\Font -> getSize()

4)是否加粗:\PhpOffice\PhpWord\Style\Font -> isBold()

5)读取图片:\PhpOffice\PhpWord\Element\Image -> getImageStringData()

6)ba64格式图片数据保存为图片:file_put_contents($imageSrc, base64_decode($imageData))

四、完整代码

 require './vendor/autoload.php';
 function docx2html($source)
 {
     $phpWord = \PhpOffice\PhpWord\IOFactory::load($source);
     $html = '';
     foreach ($phpWord->getSections() as $section) {
         foreach ($section->getElements() as $ele1) {
             $paragraphStyle = $ele1->getParagraphStyle();
             if ($paragraphStyle) {
                 $html .= '
             } else {
                 $html .= '
';             }             if ($ele1 instanceof \PhpOffice\PhpWord\Element\TextRun) {                 foreach ($ele1->getElements() as $ele2) {                     if ($ele2 instanceof \PhpOffice\PhpWord\Element\Text) {                         $style = $ele2->getFontStyle();                         $fontFamily = mb_convert_encoding($style->getName(), 'GBK', 'UTF-8');                         $fontSize = $style->getSize();                         $isBold = $style->isBold();                         $styleString = '';                         $fontFamily && $styleString .= "font-family:{$fontFamily};";                         $fontSize && $styleString .= "font-size:{$fontSize}px;";                         $isBold && $styleString .= "font-weight:bold;";                         $html .= sprintf('%s',                             $styleString,                             mb_convert_encoding($ele2->getText(), 'GBK', 'UTF-8')                         );                     } elseif ($ele2 instanceof \PhpOffice\PhpWord\Element\Image) {                         $imageSrc = 'images/' . md5($ele2->getSource()) . '.' . $ele2->getImageExtension();                         $imageData = $ele2->getImageStringData(true);                         // $imageData = 'data:' . $ele2->getImageType() . ';base64,' . $imageData;                         file_put_contents($imageSrc, base64_decode($imageData));                         $html .= '';                     }                 }             }             $html .= '
';
         }
     }
 return mb_convert_encoding($html, 'UTF-8', 'GBK');
 }
 $dir = str_replace('\', '/', DIR) . '/';
 $source = $dir . 'test.docx';
 echo docx2html($source);     

五、补充

很明显,这是一个简陋的word读取示例,只读取了段落的对齐方式,文字的字体、大小、是否加粗及图片等信息,其他例如文字颜色、行高。。。等等信息都忽悠了。需要的话,请自行查看phpWord源码,看\PhpOffice\PhpWord\Style\xxx 和 \PhpOffice\PhpWord\Element\xxx 等类里有什么读取方法就可以了

六、2020-07-21 补充

可以用以下方法直接获取到完整的html

$phpWord = \PhpOffice\PhpWord\IOFactory::load('xxx.docx');
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML");
$html = $xmlWriter->getContent();

注:html内容里包含了head部分,如果只需要style和body的话,需要自己处理一下;然后图片是base64的,要保存的话,也需要自己处理一下

base64数据保存为图片请参考上面代码

如果只想获取body里的内容,可以参考 \PhpOffice\PhpWord\Writer\HTML\Part\Body 里的 write 方法
复制代码

$phpWord = \PhpOffice\PhpWord\IOFactory::load('xxxx.docx');
$htmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML");
$content = '';
foreach ($phpWord->getSections() as $section) {
$writer = new \PhpOffice\PhpWord\Writer\HTML\Element\Container($htmlWriter, $section);
$content .= $writer->write();
}
echo $content;exit;

图片的处理的话,暂时没有好办法能在不修改源码的情况下处理好,改源码的话,相关代码在 \PhpOffice\PhpWord\Writer\HTML\Element\Image 里

public function write()
 {
     if (!$this->element instanceof ImageElement) {
         return '';
     }
     $content = '';
     $imageData = $this->element->getImageStringData(true);
     if ($imageData !== null) {
         $styleWriter = new ImageStyleWriter($this->element->getStyle());
         $style = $styleWriter->write();
         // $imageData = 'data:' . $this->element->getImageType() . ';base64,' . $imageData;
         $imageSrc = 'images/' . md5($this->element->getSource()) . '.' . $this->element->getImageExtension();
         // 这里可以自己处理,上传oss之类的
         file_put_contents($imageSrc, base64_decode($imageData));
     $content .= $this->writeOpening();     $content .= "<img border=\"0\" style=\"{$style}\" src=\"{$imageSrc}\"/>";     $content .= $this->writeClosing(); } return $content;
 }

使用Phpword实现word转html

//Word转HTML
$phpWord = \PhpOffice\PhpWord\IOFactory::load('./word/hello.docx');
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML");
$xmlWriter->save('./html/hello.html');