0%

抽象工厂模式设计的一款工具项目,方便快速实现html转PDF、doc转PDF等功能

项目源代码:github/simple-convert

如何使用

  • 使用Maven下载依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>com.liumapp.simple.convert</groupId>
    <artifactId>simple-convert</artifactId>
    <version>v1.0.0</version>
    </dependency>
  • 拷贝repo目录到本地项目中,否则会提示找不到aspose的jar包

    当然,您也可以自行将libs目录下的aspose这个jar包部署到自己的nexus私服或者导入maven的本地仓库中

  • html转doc

    • 通过文件目录转换

      1
      2
      3
      4
      BasicConverter converter = new HtmlToPdfConverterFactory().getInstance();
      String htmlFilePath = HtmlToPdfConverterTest.class.getClassLoader().getResource("test.html").getPath();
      String pdfResultPath = "./result.pdf";
      converter.convertByFilePath(htmlFilePath, pdfResultPath);

      执行后将htmlFilePath所指向的html文件转换为pdf文件,并保存在pdfResultPath路径下

    • 通过输入流转换

      1
      2
      3
      4
      5
      6
      7
      8
      BasicConverter converter = new HtmlToPdfConverterFactory().getInstance();
      String targetFilePath = HtmlToPdfConverterTest.class.getClassLoader().getResource("test.html").getPath();
      InputStream is = new FileInputStream(targetFilePath);
      OutputStream os = new FileOutputStream(new File("./result2.pdf"));
      converter.convertByStream(is, os);
      os.flush();
      is.close();
      os.close();

      将要转换的html文件作为输入流输出,输出流为要存储的pdf文件输出流,也可以使用ByteArrayOutputStream暂存在内存中

    • 通过base64转换

      1
      2
      3
      4
      5
      6
      BasicConverter converter = new HtmlToPdfConverterFactory().getInstance();
      String targetFilePath = HtmlToPdfConverterTest.class.getClassLoader().getResource("test.html").getPath();
      InputStream is = new FileInputStream(targetFilePath);
      String inputBase64 = Base64FileTool.inputStreamToBase64(is);
      String resultBase64 = converter.convertByBase64(inputBase64);
      is.close();

      inputBase64为html文件内容的base64值,输出的resultBase64为转换后的pdf base64值

    • 直接传入html字符串转pdf文件

      同通过base64转换一样,将html字符串加密为base64值,将转换后的base64解密存储即可得到pdf文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
                   BasicConverter converter = new HtmlToPdfConverterFactory().getInstance();
      String htmlContents = "<h3>你的第一个html转PDF文档出来啦!!</h3>\n" +
      "<br>\n" +
      "<div style=\"color: aquamarine\">\n" +
      " 注意:html5以及css3的支持还不够完善!!!\n" +
      "</div>\n";
      String inputBase64 = Base64.getEncoder().encodeToString(htmlContents.getBytes());
      String resultBase64 = converter.convertByBase64(inputBase64);
      Base64FileTool.saveBase64File(resultBase64, "./result10.pdf");
      ````

      Base64FileTool这个类来自于qtools-file依赖

      * doc转pdf

      * 通过文件目录转换

      ````java
      BasicConverter converter = new DocToPdfConverterFactory().getInstance();
      converter.convertByFilePath("./data/test.doc", "./result4.pdf");
      ````

      * 通过输入流转换

      ````java
      BasicConverter converter = new DocToPdfConverterFactory().getInstance();
      FileInputStream is = new FileInputStream("./data/test.doc");
      FileOutputStream os = new FileOutputStream("./result5.pdf");
      converter.convertByStream(is, os);
      is.close();
      os.close();

注意事项

  • 在pom.xml中,不要使用system scope引入jar包,而要通过在项目设立一个maven本地仓库:repo目录,将所需要的第三方jar包deploy进去(不能直接从maven下载,原因你懂的)

    • system scope引入的包,在使用jar-with-dependencies打包时将不会被包含,可以使用resources将本地包打进jar-with-dependencies

    • 关于本地repositor的创建和使用,可以参考 这里

  • html转PDF的功能还不够完善,不能完美支持:html5 + css3(或者说能够完美支持html5 + css3的破解版本还没有出来)

  • 所有转换默认是以A4纸作为最终的PDF页面大小,如果要进行更改的话,请直接使用BasicConverter的getDocument和getDocumentBuilder方法,在获取到Document对象或者DocumentBuilder对象后,修改pageSetup的相关属性,具体请参考aspose的文档

    或者直接参考这一段代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    BasicConverter converter = new HtmlToPdfConverterFactory().getInstance();
    DocumentBuilder builder = converter.getDocumentBuilder();
    PageSetup pageSetup = builder.getPageSetup();
    pageSetup.setPageWidth(2000);
    pageSetup.setPageHeight(100);
    String htmlFilePath = HtmlToPdfConverterTest.class.getClassLoader().getResource("test.html").getPath();
    String pdfResultPath = "./result11.pdf";
    converter.convertByFilePath(htmlFilePath, pdfResultPath);
    assertEquals(true, FileTool.isFileExists("./result11.pdf"));
阅读全文 »

很多优秀的Java项目实际上并不提供免费使用,比如aspose,而作为个人的话一般而言都会选择它的破解版本来研究,那么破解后的jar包肯定是不能直接在Maven的中央仓库下载到的,我们只能选择本地导入或者私服的方式来加载,后者会要求你具备nexus私服系统,前者若通过system scope来导入的话,是无法使用使用jar-with-dependencies进行打包的,那么这里提供另一种实现方式:在项目下创建一个repository来加载

先上项目源代码:github/simple-convert

创建本地repository

  • 进入项目根目录,假设我们有一个名为libs的目录,libs下面有一个名为aspose-words-15.8.0-jdk16.jar的jar包(破解好的jar包)

  • 在项目根目录下创建一个名为repo的目录,接下来把这个目录作为我们的本地repository

  • 在libs目录下执行命令,将aspose的jar包deploy到repo下面

    1
    mvn deploy:deploy-file -DgroupId=com.aspose.words -DartifactId=aspose-words -Dversion=15.8.0 -Dpackaging=jar -Dfile=./aspose-words-15.8.0-jdk16.jar -Durl=file://${您的项目根目录绝对地址}\repo\
  • build success后我们应该可以在repo目录下观察到理想的结果:

1.png

配置pom.xml

  • 首先配置我们刚刚添加的本地repository

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	 <repositories>
    <repository>
    <id>project.local</id>
    <name>project</name>
    <url>file:${project.basedir}/repo</url>
    </repository>
    </repositories>
    ```

    * 接下来直接使用aspose的jar包便可
    com.aspose.words aspose-words 15.8.0 ```

总结

通过这种方式来让maven加载本地的jar包,可以规避 system scope 所会带来的问题,同时能够最大化避免跟其他plugin(打jar包的plugin)所可能产生的冲突

那么还有一个新的问题,如果我们现在的这个项目: simple-converter发布到Maven中央仓库,然后其他客户加载它的依赖后,aspose的这个jar包能否下载到呢?

阅读全文 »

一条命令在docker中启动solo,所有麻烦的配置全部用docker-compose编排解决

项目地址: github/solo-in-docker

如何使用

  • 确保系统环境具有docker + docker-compose

    检查命令:

    1
    2
    docker -v
    docker-compose -v
  • 配置docker-compose.yml文件,需要注意的事项已经全部//备注好了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
        services:
    mysql:
    container_name: mysql
    image: mysql:5.5.60
    restart: always
    volumes:
    - ./mysql/data:/var/lib/mysql //mysql的数据文件存放地址
    - ./mysql/conf/mysqld.conf:/etc/mysql/mysql.conf.d/mysqld.cnf //mysql的配置文件存放地址
    ports:
    - "6603:3306" //6603代表宿主机端口,3306代编容器的端口
    environment:
    - MYSQL_ROOT_PASSWORD=adminadmin //mysql的root账号密码
    solo:
    container_name: solo
    image: b3log/solo //直接使用最新版本的solo镜像
    restart: always
    ports:
    - "8080:8080" //如果要部署到线上的话,请改为"80:80"
    environment: //此处配置solo跟mysql的连接设置,来源为上面启动的mysql容器,如果要用自己的mysql服务,那么请将mysql的servcie去掉
    RUNTIME_DB: "MYSQL"
    JDBC_USERNAME: "root"
    JDBC_PASSWORD: "adminadmin"
    JDBC_DRIVER: "com.mysql.jdbc.Driver"
    JDBC_URL: "jdbc:mysql://mysql:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC" //此处,因为solo跟mysql同为docker容器,所以可以直接使用容器名 + 容器端口来访问
    command: --listen_port=8080 --server_scheme=http --server_host=www.liumapp.com //按照solo官方要求,在solo启动之初,配置solo的域名、端口,如果是本地测试的话,将host改为localhost即可
    ````

    * 启动命令

    ````shell
    docker-compose up -d
  • 停止命令

    1
    docker-compose down
  • 查看solo日志的命令

    docker logs -t -f --tail 100 solo

效果展示

http://www.liumapp.com

阅读全文 »

还是同样使用mybatis-generator-plugin插件过程中遇到的问题,不过这个比较简单,配置一下时区即可

更新mysql连接的url,将时区信息带上去,我们北京是东8时区,所以是GMT+8

具体代码如下:

jdbc:mysql://localhost:3306/solo?serverTimezone=GMT%2B8

也顺便记录一下我常用的mysql连接配置:

jdbc:mysql://localhost:3306/solo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false

阅读全文 »

今天在使用mybatis-generator-plugin的过程中,遇到一个异常:Unknown system variab
le ‘tx_isolation’

仔细谷歌了一下,发现这是由于mysql版本更新的问题造成的,我们以前一直习惯于使用mysql5.x版本,但是更新到mysql8.x之后,tx_isolation这个字段被移除掉了,所以产生这个问题

解决办法分两种情况来考虑:

  • 具体代码中使用

    如果在具体业务代码中,操作数据库CURD遇到这个异常,只需要更换mysql-connector-java的依赖版本即可

    1
    2
    3
    4
    5
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.13</version>
    </dependency>
  • mybatis-generator-plugin中使用

    如果是在mybatis-generatotr-plugin中使用,遇到这个问题,那么我们需要调整generatorConfig.xml配置文件:

    使用8.x版本的mysql-connector~

    1
    <classPathEntry location="C:\Users\lenovo\.m2\repository\mysql\mysql-connector-java\8.0.12\mysql-connector-java-8.0.12.jar"/>
阅读全文 »

实际开发过程中,我们经常会需要将线上数据库的数据备份到本地,但是由于这个数据量过大,所以在本地执行sql的过程中,往往会碰到[ERR] 2006 - MySQL server has gone away这个问题,这篇文章记录一下这个问题的出现原因和解决办法

MySQL服务连接超时断开了连接

这是最常见的原因,解决办法也很简单,需要我们确保mysql的wait_timeout的值和interactive_timeout的值足够大

具体修改sql语句(在mysql命令行或者相关工具中运行):

首先检查wait_timeout的值

1
show global variables like 'wait_timeout';

如果查询到的结果是28800的话(单位是秒),那么就是默认值,也就是8个小时,那么先不改它,够大了

然后检查interactive_timeout的值

1
show global variables like 'interactive_timeout';

如果没做修改的话,应该也是28800,先不改

阅读全文 »

从jdk1.8开始,Oracle重写了日期与时间的实现。虽然我们仍然可以使用过去的方法来实现,但是掌握最新的方法可以更高效的解决时间日期相关的问题。

项目源代码:github/liumapp/dates-and-times-in-jdk1.8

1. 如何运行案例代码

1.1 编译

直接在项目根目录下使用gradle执行编译命令:

1
gradle build

编译成功后会在build/libs/目录下生成可执行jar包

1.2 直接启动案例demo

这个案例项目同时支持纯命令行界面与java swing风格的界面,前者通过命令行启动,后者直接在文件夹中双击jar包即可。

阅读全文 »

笔者从2017年开始陆陆续续在Maven中央仓库发布了15+个项目,但是今天对旧项目进行版本更新的过程中发现一样的代码,却死活无法通过Maven的gpg认证,一直卡死在operation time out这个问题上,研究了三个小时,终于解决。

关于如何在Maven中央仓库上发布项目,各位看官可以参考我的这两篇博客:

问题产生原因

发布项目到Maven中央仓库无法通过gpg认证,其实跟代码没有关系,问题出现在自己的gpg密钥对上(花了3个小时买来的教训)

我们生成gpg密钥对,仅仅是将公钥发布到线上服务器,私钥仍然是保存在本地的,也许很多人对此就没有再深究过,而忽视了密钥对本身是有使用期限的,没错,使用期限,而且这个期限默认是在两年以内…

那么我2017年生成的密钥对,到了2019年如果继续使用的话,就会产生死活无法通过gpg认证的问题

解决办法

  • 删除旧的密钥对,在命令行中输入以下命令删除

    1
    gpg --delete-secret-key liumapp

    这里的liumapp是我个人在生成密钥对时,所设置的姓名

    可能有人会问,那么发布到线上服务器的公钥如何删除呢?很抱歉,我不知道,装作看不见好了

    当然,也不要因为这个,就想偷懒不发布新生成密钥对的公钥,这样做的话发布项目到Maven中央仓库的时候,会报找不到公钥的异常(不要问我是怎么知道的…)

  • 重新生成新的密钥对,并发布即可

    具体方法各位可以参考我的这篇博客:

    gpg的安装使用

阅读全文 »

Travis CI 教程,主要介绍如何使用Travis CI的检验代码功能和Code Review功能.

A tutorial of Travis CI mainly introduces how to use Travis CI’s checking code function and Code Review function.

项目源码:github/hello-travis-ci

目录

1. 检验代码

1.1 注册Travis-CI

在GitHub的marketplace中搜索Travis CI,然后下载,并关联自己的GitHub账号

ps: Travis CI只支持在GitHub使用

register.png

阅读全文 »

百度OCR接口操作工具类,不依赖第三方框架实现,让您5行代码即可调用百度OCR的各个接口

项目代码:github/baidu-ocr-operator

如何使用

  • Maven加载项目依赖
1
2
3
4
5
<dependency>
<groupId>com.liumapp.operator.baidu.ocr</groupId>
<artifactId>baidu-ocr-operator</artifactId>
<version>v1.0.2</version>
</dependency>
  • 配置应用,在您的项目resources目录下创建一个baidu-ocr.yml文件(需要严格注意文件命名),并配置您的应用信息
1
2
3
4
5
6
7
com:
liumapp:
baidu:
ocr:
appId: 'your app id here'
appKey: 'your app key here'
appSecret: 'your app secret here'

营业执照OCR

1
2
3
4
5
6
OcrOperator ocrOperator = new OcrOperator();
BusinessLicenseOcr businessLicenseOcr = new BusinessLicenseOcr();
BusinessLicenseOcrRequire businessLicenseOcrRequire = new BusinessLicenseOcrRequire();
businessLicenseOcrRequire.setLicensePicPath(dataPath + "/businessLicense01.jpg");
JSONObject res = ocrOperator.doJob(businessLicenseOcr, businessLicenseOcrRequire);
System.out.println(res.toJSONString());

驾驶证OCR

阅读全文 »