整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

网页截图和svg模版动态生成图片Java实现

Java实现根据svg模版动态生成图片

使用场景

需要Java语言动态生成图片

用流程图简单说明下我这边工作中使用的场景

仅供参考

所以这里就需要生成证书了

我先给大家看下最终实现的图片效果

这里要先说明一下

  • 图片上的文字都是动态变化的即不同的订单对应的图片内容都不一样
  • 图片上还可以嵌入图片哦 比如上图的logo图片

下面说下我是如何解决的

通过PhantomJS来实现

这种方式是不能实现这个需求的

这个的原理就是对网页截图 但只能对于静态页面截图 不能根据不同的参数值动态生成图片

所以不提倡使用这种方式

但也介绍下这种使用方式 朋友们根据自己的实际需求情况有选择的使用

通过html代码实现图片的效果 放入web容器(比如nginx)中部署

这是h5代码

test文件夹下面的内容

安装一个docker nginx 将test文件夹加载到nginx容器的/usr/share/nginx/html目录下面

docker run --name nginx80  -p 8000:80  -v /tmp/test:/usr/share/nginx/html -d docker.io/nginx

访问的页面效果

访问该页面进行截图

这张图片是截图生成的图片 但url中的id值并没有传给页面

在h5代码中请求后端接口获取数据动态显示出来也是不可以的

所以这种方式使用局限性很窄

简单介绍下代码原理

大致原理是 通过http请求该url获取该url的文件流然后解析h5代码生成图片

通过SVG模版动态生成

先写svg模版(其实也是h5代码)

读取svg模版 动态传入参数生成图片

其实现原理大致为 读取svg document h5代码 将动态参数map解析到h5代码中 转换成字节数组 生成图片格式

Linux环境图片中文乱码

我本地是mac系统没有这个问题 在发布到测试环境linux系统出现了这个问题

先看下问题的现象

看到了没 生成的图片中文全是乱码

原因是因为linux系统没有中文字体

既然linux系统没有中文字体 那么就安装它嘛 let's 盘它!!!

先看下mac环境的字体情况

  • 安装字体管理工具
brew install fontconfig
  • 查看支持中文
fc-list :lang=zh    (注意‘:’前的空格)

mac环境默认会安装很多中文字体

再看下linux环境

  • 安装字体管理工具
yum -y install fontconfig
  • 查看支持中文
fc-list :lang=zh

果然没有中文字体

开始安装中文字体

将mac环境的宋体上传到linux环境

a 先在mac系统中找到字体安装目录

/System/Library/Fonts

b 找到宋体对应的文件

c 将该文件上传到linux指定的目录下

/usr/share/fonts/chinese

d 赋予文件夹操作权限

chmod -R 755 /usr/share/fonts/chinese

e 安装ttmkfdir来搜索目录中所有的字体信息,并汇总生成fonts.scale文件

yum -y install ttmkfdir

ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir

修改字体配置文件

vi /etc/fonts/fonts.conf
添加
<dir>/usr/share/fonts/chinese</dir>

刷新内存中的字体缓存

fc-cache

确认是否安装成功

在jdk中安装该宋体

a 找到jdk所在的安装目录

echo $JAVA_HOME 

b 将宋体文件复制过来

cp /usr/share/fonts/chinese/STHeiti\ Light.ttc /usr/local/software/jdk1.8.0_141/jre/lib/fonts/fallback

fallback代表存放后备语言的文件夹

重启java服务即可

DEMO代码

https://gitee.com/pingfanrenbiji/resource/tree/master/image

注意: 引入的依赖问题

  <!--phantomjs -->
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-java</artifactId>
   <version>2.53.1</version>
  </dependency>
  <dependency>
   <groupId>com.github.detro</groupId>
   <artifactId>ghostdriver</artifactId>
   <version>2.1.0</version>
  </dependency>

  <!--svg-->
  <dependency>
   <groupId>com.github.hui.media</groupId>
   <artifactId>svg-core</artifactId>
   <version>2.5</version>
  </dependency>

这些依赖jar包我是上传到了公司的私服上了

若是朋友们下拉不下来

我提供给大家这些底层jar包的实现源码

https://gitee.com/pingfanrenbiji/quick-media

自行上传到自己的私服即可

前言

Java编程生成word文档这种操作一般是常规操作比较常见,主要采用Apache的POI Word 这个库操作的比较多,还有的用Spire.Doc,但是这个库有些稍微难点的功能要收费,看了下费用还不低,周末朋友问起是否有用java操作word加上下标的经验,我是没有的,不过刚好借机研究下。 本文主要聊下POI,毕竟是免费的,更值得研究。

word 格式说明和POI支持情况: HWPF: MS-Word 97-2003(.doc),基于BIFF8格式的JAVA接口。只支持.doc文件简单的操作,读写能力有限。本API为POI项目早期开发,很不幸的 是主要负责HWPF模块开发的工程师-"Ryan Ackley"已经离开Apache组织,现在该模块没有人维护、更新、完善。 XWPF:MS-Word 2007+(.docx),基于OOXML格式的JAVA接口。较HWPF功能完善。

二 安装

都是利用的jar,不存在什么安装,直接配置pom文件即可。 添加POI的word的jar:

        <!-- 操作excel的库 注意版本保持一致 poi poi-ooxml  poi-scratchpad -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>

    
 <!--poi-ooxml和*poi-ooxml-schemas*是poi对2007及以上版本的扩充。-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>

   <!--poi-ooxml和*poi-ooxml-schemas*是poi对2007及以上版本的扩充。-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>4.1.2</version>
      <scope>compile</scope>
    </dependency>
      

     <!-- WordToHtml .doc .odcx  poi  -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>
 

三 基本使用

3.1 核心类

最核心的三个类: XWPFDocument : 文档本身的抽象、代表整个文档; XWPFParagraph: 段落、整个文档可以看做一个个段落组成、简单对应我们文章的段落; XWPFRun: 可以看做一个片段,整个段落由多个Run组成、每个Run可以有自己的文字内容、样式等。

XWPFTable: 表格,和段落平级;

3.2 文档

创建文档

XWPFDocument doc = new XWPFDocument();
或
XWPFDocument doc = new XWPFDocument(new FileInputStream("./deepoove.docx"));

获取文档上的元素、比如段落、表格、图片等。

// 段落
List<XWPFParagraph> paragraphs = doc.getParagraphs();
// 表格
List<XWPFTable> tables = doc.getTables();
// 图片
List<XWPFPictureData> allPictures = doc.getAllPictures();
// 页眉
List<XWPFHeader> headerList = doc.getHeaderList();
// 页脚
List<XWPFFooter> footerList = doc.getFooterList();

生成文档

try (FileOutputStream out = new FileOutputStream("simple.docx")) {
    doc.write(out);
}

3.3 段落

创建段落

XWPFParagraph p1 = doc.createParagraph();

段落样式设置:

// 对齐方式
p1.setAlignment(ParagraphAlignment.CENTER);
// 边框
p1.setBorderBottom(Borders.DOUBLE);
p1.setBorderTop(Borders.DOUBLE);
p1.setBorderRight(Borders.DOUBLE);
p1.setBorderLeft(Borders.DOUBLE);
p1.setBorderBetween(Borders.SINGLE);

3.4 基本样式Run

Run是段落的基本组成单元,可以是一段文字、也可以是一张图片、可以设置自己的不同样式风格。

获取段落内容

// 获取文字
String text = paragraph.getText();
// 获取段落内所有XWPFRun
List<XWPFRun> runs = paragraph.getRuns();

创建run

// 段落末尾创建XWPFRun
XWPFRun run = paragraph.createRun();
run.setText("为这个段落追加文本");

// 颜色
run.setColor("00ff00");
// 斜体
run.setItalic(true);
// 粗体
run.setBold(true);
// 字体
run.setFontFamily("Courier");
// 下划线
run.setUnderline(UnderlinePatterns.DOT_DOT_DASH);

获取段落中run和修改run

// 获取文字
String text = paragraph.getText();
// 获取段落内所有XWPFRun
List<XWPFRun> runs = paragraph.getRuns();

// 段落起始插入XWPFRun
XWPFRun insertNewRun = paragraph.insertNewRun(0);
insertNewRun.setText("在段落起始位置插入这段文本");

修改run

List<XWPFRun> runs = paragraph.getRuns();
// setText默认为追加文本,参数0表示设置第0个位置的文本,覆盖上一次设置
runs.get(0).setText("追加文本", 0);
runs.get(0).setText("修改文本", 0);

文本换行

run.addCarriageReturn();

3.5 关于图片

提取文档图片

List<XWPFPictureData> allPictures = doc.getAllPictures();
XWPFPicture pciture = allPictures.get(0);
byte[] data = pciture.getPictureData().getData();
// 接下来就可以将图片字节数组写入输出流

利用XWPFRun创建图片

List<XWPFPictureData> allPictures = doc.getAllPictures();
XWPFPicture pciture = allPictures.get(0);
byte[] data = pciture.getPictureData().getData();
// 接下来就可以将图片字节数组写入输出流

3.6 表格

创建三行三列的表格

 XWPFTable table = doc.createTable(3, 3);

设置单元格的文本 表格是由表格行XWPFRow构成,每行是由单元格XWPFCell构成,每个单元格内部又是由许多XWPFParagraph段落构成。

table.getRow(1).getCell(1).setText("EXAMPLE OF TABLE");

上面代码和下面代码等价:

XWPFParagraph p1 = table.getRow(0).getCell(0).addParagraph();
XWPFRun r1 = p1.createRun();
r1.setText("EXAMPLE OF TABLE")

设置单元格里面的图片,可以按照上述办法获取到单元格的XWPFRun然后按照run添加图片的办法进行。

设置单元格的样式

XWPFParagraph p1 = table.getRow(0).getCell(0).addParagraph();
XWPFRun r1 = p1.createRun();
r1.setText("EXAMPLE OF TABLE")

四 实例

public class TestFirstDoc {

    public static void main(String[] args) throws IOException, InvalidFormatException {
        XWPFDocument document = new XWPFDocument();
        FileOutputStream out = new FileOutputStream(new File("测试文档.docx"));
        XWPFParagraph paragraph = document.createParagraph();

        // 基本测试
        XWPFRun paragraphOneRunOne = paragraph.createRun();
        paragraphOneRunOne.setText("测试第一个Run");
        paragraphOneRunOne.setBold(true);
        paragraphOneRunOne.setItalic(true);
        paragraphOneRunOne.addBreak();

        // 样式测试
        XWPFRun paragraphRun2 = paragraph.createRun();
        paragraphRun2.setText("为这个段落追加文本");
        paragraphRun2.setFontSize(20);
        paragraphRun2.setColor("00ff00");
        paragraphRun2.setFontFamily("Courier");
        paragraphRun2.setUnderline(UnderlinePatterns.DOT_DOT_DASH);

        // 上下标测试
        XWPFRun paragraphRun3 = paragraph.createRun();
        paragraphRun3.setText("设置正常文字");


        XWPFRun paragraphRun4 = paragraph.createRun();
        paragraphRun4.setText("上标");
        paragraphRun4.setItalic(true);
        paragraphRun4.setSubscript(VerticalAlign.SUPERSCRIPT);

        XWPFRun paragraphRun5 = paragraph.createRun();
        paragraphRun5.setText("下标");
        paragraphRun5.setItalic(true);
        paragraphRun5.setSubscript(VerticalAlign.SUBSCRIPT);

        // 设置换页,表格和上面内容分开来
        XWPFParagraph paragraph2 = document.createParagraph();
        paragraph2.setPageBreak(true);

        
        XWPFTable table = document.createTable(3, 3);
        table.getRow(0).getCell(0).setText("Head1");
        table.getRow(0).getCell(1).setText("Head2");
        table.getRow(0).getCell(2).setText("Head3");

        table.getRow(1).getCell(0).setText("col1");
        table.getRow(1).getCell(1).setText("col2");
        table.getRow(1).getCell(2).setText("col3");

        XWPFParagraph p1 = table.getRow(2).getCell(0).addParagraph();
        XWPFRun r1 = p1.createRun();
        InputStream stream = new FileInputStream("D:\\1.jpg");
        r1.addPicture(stream, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(256), Units.toEMU(256));


        document.write(out);
        out.close();
        System.out.println("测试完成");

    }
}

效果图:

第二页:

些初学web前端的小伙伴会比较迷惑,HTML到底是什么呢?

这里解释一下,HTML称为超文本标记语言,是一种标识性的语言。

它包括一系列标签,通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整体。HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字,图形、动画、声音、表格、链接等。

HTML的学习也是要由浅到深一步一步学习,对于很多小伙伴来说,HTML的学习路线一直是一个问题,下边我列出HTML需要学习的几个知识点,大家可以作为参考。

HTML学习路线:

⒈ html概述

html基本标签

⒊ 图片标签

⒋ 超链接标签

⒌ 表格标签

⒍ 无序列表标签

⒎ 有序列表标签

⒏ 定义列表标签

⒐ div标签

⒑ 语义化标签

⒒ 表单标签

⒓ 语义化表单元素

⒔ 框架标签

⒕ 特殊字符

⒖ 综合案例

针对以上的html知识点,动力节点也有非常适合初学者的HTML学习教程,相信大家通过HTML视频课程的学习以后,会对HTML有一个深入的了解。

HTML教程内容涵盖:

  • HTML基础语法
  • HTML概述
  • W3C概述
  • B/S架构系统原理
  • table
  • 背景色与背景图片
  • 超链接
  • 列表
  • 表单
  • 框架等知识点

通过该视频的学习之后,可以开发基本的网页,并且可以看懂别人编写的HTML页面。

HTML学习资料:http://www.bjpowernode.com/?toutiaohtml.chai