码迷,mamicode.com
首页 > 移动开发 > 详细

【原创】Java小App解决Jupyter Notebook导出PDF不显示中文

时间:2018-10-11 01:46:28      阅读:824      评论:0      收藏:0      [点我收藏+]

标签:bubuko   doc   jupyter   ESS   str   lan   releases   图片   for   

1.【问题背景】

  1.1最近写了一个大数据的小练习,感觉那个有点用,就想导出PDF去打印

    然后问题来了:导出的PDF不显示中文!!!(可惜那一块多钱)。然后探索的过程就开始了

  1.2 一有问题当然是先问度娘了,找了一波后发现可以通过命令提示符(CMD)以命令的方式创建创建出pdf,这就很灵性了。

    虽然直接在Jupyter Notebook里可以更简单地直接导出PDF,

    但是对于希望在PDF里显示中文的同学来说,能够方便一点导出pdf文件的话,何乐而不为嘞

2.【基本过程】

    2.1 我找的解决方案挺简单的,大概分三步:a): 一条命令通过source.ipynb文件生成source.tex文件 

                       b): 用编辑器打开source.tex,在指定位置添加文本

                       c):一条命令通过source.tex文件生成一系列文件,这里面就包括了source.pdf

                       d):上面的处理方式都是通过Java实现,在控制台运行指令也是通过Java调用的(真好玩)

                       嘿嘿,听起来挺简单的,写着写着你会发现还真的挺简单的,还有一点瓜

3.【操作环境以及相关准备】

  3.1   win10+IDEA+jdk8+anaconda+Jupyter Notebook+MikTeX+Pandoc+JavaFx(SceneBuilder)

  3.2   要通过Jupyter Notebook转PDF的话要用MikTeX和Pandoc,MikTeX需要配置环境

  3.3    MikTeX下载地址:https://miktex.org/download              

     Pandoc下载地址:https://github.com/jgm/pandoc/releases/tag/2.3.1

  3.4    把MikTex添加到系统环境变量里

      技术分享图片


 

4.【Java控制台实现方式】

  4.1 介绍:最初就是写了一个控制台程序,然后为了能够成功导出PDF就一直在堆代码,最后就是成功导出PDF

  4.2 代码:因为一开始就是为了写功能而写代码,所以感觉把这个写死了,因为测试就是针对一个文件来写的,不过问题不大,后面我又写了一个JavaFx的

       相关注释我都写在里面了

    

技术分享图片
  1 import java.io.*;
  2 
  3 public class Main {
  4 
  5     private static String path = "D:\\JupyterNotebook";
  6     private static File sourceFile = new File("D:\\JupyterNotebook\\pandas_test.tex");
  7 
  8     public static void main(String[] args) throws IOException, InterruptedException {
  9         for (int i = 0; i < args.length; i++) {
 10             System.out.println(args[i]);
 11         }
 12         change2Tex();
 13         File bufferFile = createTexFile();  //获取创建的文件对象
 14         delay() ;                           //延时
 15         modifyTex(bufferFile);              //修该Tex文件
 16         change2PDF();                       //将Tex文件转化成PDF文件
 17     }
 18 
 19 
 20     /**
 21      * 延一个时,
 22      * java建文件比命令提示符快
 23      *
 24      * @throws InterruptedException
 25      */
 26     public static void delay() throws InterruptedException {
 27         for (int i = 0; i < 4; i++) {
 28             Thread.sleep(1000);
 29         }
 30     }
 31 
 32     /**
 33      * 通过简单的命令
 34      * 将文件转化为tex文件
 35      * 执行cmd
 36      *
 37      * jupyter nbconvert --to latex yourNotebookName.ipynb
 38      * 将文件里   \documentclass[11pt]{article}后面加上下面这三行
 39      * \\usepackage{fontspec, xunicode, xltxtra}
 40      * \\setmainfont{Microsoft YaHei}
 41      * 将latex转化为pdf
 42      * xelatex yourNotebookName.tex
 43      */
 44     public static void change2Tex() throws IOException {
 45 
 46         Runtime runtime = Runtime.getRuntime();
 47         String cmd = "cmd /k start  jupyter nbconvert --to latex " + path + "\\pandas_test.ipynb";  //cmd指令,cmd /k start + 指令,运行五玩了指令就关闭cmd
 48         System.out.println(cmd);
 49         System.out.println(path);
 50         runtime.exec(cmd);
 51     }
 52 
 53     /**
 54      * 将tex文件转化成pdf文件
 55      *
 56      * @throws IOException
 57      */
 58     public static void change2PDF() throws IOException {
 59         Runtime runtime = Runtime.getRuntime();
 60         String cmd = "cmd /k start xelatex afterInsertText.tex";
 61         runtime.exec(cmd, null, new File(path));//注意这里:exec里有三个参数,这个方法可以指定在path文件夹打开cmd,然后运行cmd指令
 62     }
 63 
 64     /**
 65      * 创建Tex文件
 66      *
 67      * @return
 68      * @throws IOException
 69      */
 70     public static File createTexFile() throws IOException {
 71 
 72         File tempFile = new File("D:\\JupyterNotebook");        //判断这个文件夹在不在
 73         if (!tempFile.exists()) {
 74             tempFile.mkdir();
 75         }
 76 
 77         File bufferTopTex = new File("D:\\JupyterNotebook", "afterInsertText.tex");     //判断这个文件在不在
 78         if (!bufferTopTex.exists()) {           //不在的话创建文件,
 79             bufferTopTex.createNewFile();
 80         }
 81         //在后面会把源.tex文件要修改的位置前面的数据写到下面这个文件(虽然下面是个对象,意思应该能懂)里面,
 82         // 然后接着在后面添加文本,最后把源tex剩下的数据写到这个文件里
 83         return bufferTopTex;
 84     }
 85 
 86     /**
 87      * 文件读写,在文件后面添加需要添加的指令
 88      *
 89      * @throws IOException
 90      */
 91     public static void modifyTex(File file) throws IOException {
 92         
 93         RandomAccessFile topTex = new RandomAccessFile(file, "rw");     //在本地创建的afterInsertText.tex文件
 94 
 95         RandomAccessFile raf = new RandomAccessFile(sourceFile, "rw");  //获取源.tex文件
 96 
 97         String line;
 98         
 99         //在下面是对readLine()取到的数据进行转码,这是一个解决乱码的好方式
100         //注意在下面每用一次readLine(),那个指向行号的指针就会向下移动一次,和ResultSet里的rs.next()有点像
101         while ((line = new String(raf.readLine().getBytes("ISO-8859-1"), "utf-8")) != null) {
102             topTex.write(("\n" + line).getBytes());
103             if (line.equals("\\documentclass[11pt]{article}")) {
104                 topTex.write((" \n\\usepackage{fontspec, xunicode, xltxtra}").getBytes());
105                 topTex.write(("\n\\setmainfont{Microsoft YaHei}").getBytes());
106                 topTex.write(("\n\\usepackage{ctex} ").getBytes());
107                 break;
108             }
109         }
110 
111         while (true) {
112             final String temp;
113             if ((temp = raf.readLine()) == null) {
114                 break;
115             } else {
116                 line = new String(temp.getBytes("ISO-8859-1"), "utf-8");
117                 topTex.write(("\n" + line).getBytes());
118             }
119         }
120     }
121 }
Main.java

 

  4.3 运行结果:emmmmmmm,这个运行完了就自己关掉了,不好截图,看看其他的吧

    技术分享图片

    4.3.1 只有一个.ipynb文件:

        技术分享图片

        然后运行一下程序:

          先是Java程序生成的afterInsertText.tex文件

        技术分享图片

 

          然后接着运行到结束就会生成这些文件,可以看到pdf自动生成了

            技术分享图片

             最后看一眼有没有中文:

          技术分享图片

 

-----------------可以看出,上面的pdf是有中文的,成功-----------------

Tip_1:在这里给出要用到的cmd命令:

  1.jupyter nbconvert --to latex yourNotebookName.ipynb


  2.将文件里 \documentclass[11pt]{article}后面加上下面这三行
                  \usepackage{fontspec, xunicode, xltxtra}
            \setmainfont{Microsoft YaHei}

              \usepackage{ctex}
  3.latex转化为pdf: xelatex yourNotebookName.tex

Tip_2:

  在Java里输出反斜杠要用两个,英文点号  ......要用  \\.


 

 

 

 

 

  

  

 

【原创】Java小App解决Jupyter Notebook导出PDF不显示中文

标签:bubuko   doc   jupyter   ESS   str   lan   releases   图片   for   

原文地址:https://www.cnblogs.com/LinKinSJ/p/9769903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!