文章目录

  • 九、文件上传与PDF报表入门
    • 1、图片上传
      • <1>、Data URL
        • (1)、概述
        • (2)、入门
        • (3)、基本原理
        • (4)、优缺点分析
      • <2>、实现用户头像上传
    • 2、七牛云存储
      • <1>、概述
      • <2>、账号申请
      • <3>、入门案例
        • (1)、环境搭建
        • (2)、文件上传
        • (3)、断点续传
      • <4>、文件下载
      • <5>、七牛云实现用户头像上传
    • 3、PDF报表打印概述
      • <1>、概述
      • <2>、 常见PDF报表的制作方式
      • <3>、JasperReport框架的介绍
    • 4、JasperReport的开发步骤
      • <1>、JasperReport生命周期
      • <2>、JasperReport原理简述
      • <3>、开发流程概述
    • 5、模板工具Jaspersoft Studio
      • <1>、概述
      • <2>、安装配置
      • <3>、面板介绍
      • <4>、基本使用
        • (1)、模板制作
        • (2)、编译模板
        • (3)、整合工程
        • (4)、中文处理

九、文件上传与PDF报表入门

1、图片上传

<1>、Data URL

(1)、概述

所谓DataURL是指"data"类型的Url格式,是在RFC2397中提出的,目的是对于一些“小”的数据,可以在网页中直接嵌入,而不是从外部文件载入。

(2)、入门
  • 完整的Data URL语法:Data URL = data:mediatype;base64,<Base64编码的数据>
  • **mediatype:**表述传递的数据的MIME类型(test/html, image/png, image/jpg)

简单的说,data类型的url大致有下面几种形式
data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<html代码>
data:text/html;base64,<base64编码的html代码>
data:text/css,<css代码>
data:text/css;base64,<base64编码的css代码>
data:text/javascript,<javascript代码>
data:text/javascript;base64,<base64编码的javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

对于在程序开发中,使用最多的是基于Data URL的图片形式,接下来以图片形式的Data URL分析原理和优缺点。

(3)、基本原理

Data URL给了我们一种很巧妙的将图片“嵌入”到HTML中的方法。跟传统的用 img 标记将服务器上的图片引用到页面中的方式不一样,在Data URL协议中,图片被转换成base64编码的字符串形式,并存储在URL中,冠以mimetype。

图片在网页中的使用方法通常是下面这种利用img标记的形式:

      <img src="images/myimage.gif ">

这种方式中,img标记的src属性指定了一个远程服务器上的资源。当网页加载到浏览器中时,浏览器会针对每个外部资源都向服务器发送一次拉取资源请求,占用网咯资源。大多数的浏览器都有一个并发请求数不超过4个的限制。这也就意味着,如果一个网页里嵌入了过多的外部资源,这些请求会导致整个页面的加载延迟,而使用Data URL技术,图片数据以base64字符串格式嵌入到了页面中,与HTML成为一体。

普通的URL和Data URL展示出的效果我们观察的话没有什么区别,但实际上它们是不一样的,一个是引用了外部资源,另一个是使用了Data URL。

(4)、优缺点分析
  • 浏览器支持
    几乎现在所有的浏览器都支持Data URL格式,包括火狐浏览器、谷歌浏览器、Safari浏览器、opera浏览器,IE8也支持,但是有部分限制,IE9完全支持
  • 数据容量
    Base64编码的数据体积是原来数据的体积4/3,也就是Data URL形式的图片会比二进制格式的图片体积大于1/3
  • 使用场景
    Data URL形式的数据不会占用HTTP会话,所以在访问外部资源或当图片是在服务器端用程序动态生成时借用Data URL是一个不错的选择。

<2>、实现用户头像上传

  • 修改用户实体类,用户返回值对象,用户数据表添加用户头像字段
  • 使用基于Data URL方式实现用户上传,实质是将前端上传的文件以Base64进行编码并且保存到数据库中。
  • 用户Controller中添加用户上传方法
  • 用户Service中添加上传文件处理的方法
  • 在Service中需要对文件进行base64编码,并且保存到数据库中

1、在系统微服务的UserController中添加上传文件处理的方法

 /*** 完成用户头像上传*/@RequestMapping(value = "/user/upload/{id}")public Result upload(@PathVariable String id, @RequestParam("file") MultipartFile file) throws IOException {//调用service保存图片(获取到图片的访问地址(dataUrl | http地址))String imgUrl = userService.uploadImage(id, file);//返回数据return new Result(ResultCode.SUCCESS, imgUrl);}

2、在系统微服务的UserService中添加上传文件处理的方法

 /*** 完成用户处理* @param id    用户id* @param file  用户上传的头像文件* @return      请求路径*/public String uploadImage(String id, MultipartFile file) throws IOException {//1、根据id查询用户User user = userDao.findById(id).get();//2、使用DataURL形式存储图片(对图片byte数组进行base64编码)String encode = "data:image/png;base64," + Base64.encode(file.getBytes());//3、更新用户头像user.setStaffPhoto(encode);userDao.save(user);//4、返回结果return encode;}

2、七牛云存储

<1>、概述

七牛云对象存储服务提供高可靠、强安全、低成本、可扩展的非结构化数据的存储服务。它提供简单的Web 服务接口,可以通过七牛开发者平台或客户端存储和检索任意数量的数据,支持 “按使用付费” 模式,可以通过调用REST API 接口和 SDK开发工具包访问,下载协议采用HTTP 和 HTTPS 协议。方便程序员聚焦业务应用,而无需关注底层存储实现技术。

使用七牛云实现图片存储也比较简单只需要按照如下的步骤操作即可:
1、申请七牛云账号
2、创建控件bucket
3、上传文件
4、请求获取图片

<2>、账号申请

1、进入官网进行用户注册即可
2、传播构建存储空间bucket

账号注册需要注意的点如下:

  • 注册账号之后需要实名认证(个人/企业)
  • 实名认证之后才可以创建存储空间
  • 存储空间创建成功之后,找到个人中心获取accessKey,secretKey和存储空间名称就可以进行上传操作了。

<3>、入门案例

(1)、环境搭建

创建一个maven工程,导入相关依赖

      <dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>[7.2.0, 7.2.99]</version></dependency>
(2)、文件上传

七牛云官方给我们提供了SDK文档,可以方便我们快速使用。

 /*** 将图片上传到七牛云服务*      1.更新用户图片信息(用户id=key)*      2.访问图片*          存储空间分配的:http://pkbivgfrm.bkt.clouddn.com*          上传的文件名*          更新图片之后:访问的时候,在请求连接添加上一个随机字符**/@Testpublic void testUpload01() {//构造一个带指定Zone对象的配置类//指定上传文件服务器地址:Configuration cfg = new Configuration(Zone.zone0());//上传管理器UploadManager uploadManager = new UploadManager(cfg);//生成上传凭证,然后准备上传String accessKey = "COuoDRVa7JLsuurzIvQSI_pEDceHDw3yGfJEmvwv";String secretKey = "3RWpTjB5Jxg3QosUFr4mxbHXJ5JR2m6AHQqYsSlr";String bucket = "ihrm-bucket";//图片路径String localFilePath = "IdeaProjects/hrm/qiniudemo/src/poi/1.jpg";//存入到存储空间的文件名String key = "test";//身份认证Auth auth = Auth.create(accessKey, secretKey);//指定覆盖上传String upToken = auth.uploadToken(bucket,key);try {//上传Response response = uploadManager.put(localFilePath, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {ex2.printStackTrace();}}}
(3)、断点续传
     /***  断点续传*/@Testpublic void testUpload02() {//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());//其他参数参考类注释//生成上传凭证,然后准备上传String accessKey = "COuoDRVa7JLsuurzIvQSI_pEDceHDw3yGfJEmvwv";String secretKey = "3RWpTjB5Jxg3QosUFr4mxbHXJ5JR2m6AHQqYsSlr";String bucket = "ihrm-bucket";String localFilePath = "IdeaProjects/hrm/qiniudemo/src/poi/test.xlsx";//默认不指定key的情况下,以文件内容的hash值作为文件名String key = "testExcel";Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);//断点续传:String localTempDir = Paths.get(System.getProperty("java.io.tmpdir"), bucket).toString();System.out.println(localTempDir);try {//设置断点续传文件进度保存目录FileRecorder fileRecorder = new FileRecorder(localTempDir);UploadManager uploadManager = new UploadManager(cfg, fileRecorder);try {Response response = uploadManager.put(localFilePath, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}} catch (IOException ex) {ex.printStackTrace();}}

<4>、文件下载

对于公开空间,其访问的链接主要是将空间绑定的域名(可以是七牛空间的默认域名或者是绑定的自定义域名)拼接上空间里面的文件名即可访问,标准情况下需要在拼接链接之前,将文件名进行urlencode以兼容不同的字符。

<5>、七牛云实现用户头像上传

1、在ihrm_common工程下创建文件上传工具类

package com.ihrm.common.utils;import com.google.gson.Gson;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;import java.util.Date;public class QiniuUploadUtil {private static final String accessKey = "COuoDRVa7JLsuurzIvQSI_pEDceHDw3yGfJEmvwv";private static final String secretKey = "3RWpTjB5Jxg3QosUFr4mxbHXJ5JR2m6AHQqYsSlr";private static final String bucket = "ihrm-bucket";private static final String prix = "http://pkbivgfrm.bkt.clouddn.com/";private UploadManager manager;public QiniuUploadUtil() {//初始化基本配置Configuration cfg = new Configuration(Zone.zone0());//创建上传管理器manager = new UploadManager(cfg);}//文件名 = key//文件的byte数组public String upload(String imgName , byte [] bytes) {Auth auth = Auth.create(accessKey, secretKey);//构造覆盖上传tokenString upToken = auth.uploadToken(bucket,imgName);try {Response response = manager.put(bytes, imgName, upToken);DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);//返回请求地址return prix+putRet.key+"?t="+new Date().getTime();} catch (Exception ex) {ex.printStackTrace();}return null;}
}

2、修改系统微服务的UserService方法

 /*** 上传到七牛云存储*/public String uploadImage(String id, MultipartFile file) throws IOException {//1、根据id查询用户User user = userDao.findById(id).get();//2、将图片上传到七牛云存储,获取请求路径String imgUrl = new QiniuUploadUtil().upload(id, file.getBytes());//3、更新用户头像user.setStaffPhoto(imgUrl);userDao.save(user);//4、返回结果return imgUrl;}

3、PDF报表打印概述

<1>、概述

在企业级应用开发中,报表生成、报表打印下载是其重要的一个环节。在之前我们已经介绍了报表中比较重要的一种:Excel报表。其实除了Excel报表之外,PDF报表也有广泛的应用场景,必须用户详细资料,用户简历等。接下来主要介绍PDF报表。

<2>、 常见PDF报表的制作方式

目前世面上比较流行的制作PDF报表的工具如下:

  • iText PDF:iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。
  • Openoffice:openoffice是开源软件且能在windows和linux平台下运行,可以灵活的将word或者Excel转化为PDF文档。
  • Jasper Report:是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF

<3>、JasperReport框架的介绍


JasperReport是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。只需要将JasperReport引入工程中即可完成PDF报表的编译、显示、输出等工作。

  • 在开源的JAVA报表工具中,JASPER Report发展是比较好的,比一些商业的报表引擎做得还好,如支持了十字交叉报表、统计报表、图形报表,支持多种报表格式的输出,如PDF、RTF、XML、CSV、XHTML、TEXT、DOCX以及OpenOffice。
  • 数据源支持更多,常用 JDBC SQL查询、XML文件、CSV文件 、HQL(Hibernate查询),HBase,JAVA集合等。还允许你义自己的数据源,通过JASPER文件及数据源,JASPER就能生成最终用户想要的文档格式。

4、JasperReport的开发步骤

<1>、JasperReport生命周期

通常我们提到PDF报表的时候,浮现在脑海中的是最终的PDF文档文件。在JasperReports中,这只是报表生命周期的最后阶段。通过JasperReports生成PDF报表一共要经过三个阶段,我们称之为JasperReport的生命周期,这三个阶段为:设计(Design)阶段、执行(Execution)阶段以及输出(Export)阶段,如下图所示:

  • 设计阶段(Design):所谓的报表设计就是创建一些模板,模板包含了报表的布局与设计,包括执行计算的复杂公式、可选的从数据源获取数据的查询语句、以及其它的一些信息。模板设计完成之后,我们将模板保存为JRXML文件(JR代表JasperReports),其实就是一个XML文件。
  • 执行阶段(Execution):使用以JRXML文件编译为可执行的二进制文件(即.Jasper文件)结合数据进行执行,填充报表数据
  • 输出阶段(Export):数据填充结束,可以指定输出为多种形式的报表

<2>、JasperReport原理简述

  • JRXML:报表填充模板,本质是一个XML.
    JasperReport已经封装了一个dtd,只要按照规定的格式写这个xml文件,那么jasperReport就可以将其解析最终生成报表,但是jasperReport所解析的不是我们常见的.xml文件,而是.jrxml文件,其实跟xml是一样的,只是后缀不一样。
  • Jasper:由JRXML模板编译生成的二进制文件,用于代码填充数据。
    解析完成后JasperReport就开始编译.jrxml文件,将其编译成.jasper文件,因为JasperReport只可以对.jasper文件进行填充数据和转换,这步操作就跟我们java中将java文件编译成class文件是一样的
  • Jrprint:当用数据填充完Jasper后生成的文件,用于输出报表。
    这一步才是JasperReport的核心所在,它会根据你在xml里面写好的查询语句来查询指定是数据库,也可以控制在后台编写查询语句,参数,数据库。在报表填充完后,会再生成一个.jrprint格式的文件(读取jasper文件进行填充,然后生成一个jrprint文件)
  • Exporter:决定要输出的报表为何种格式,报表输出的管理类。
  • Jasperreport可以输出多种格式的报表文件,常见的有Html,PDF,xls等

<3>、开发流程概述

  • 制作报表模板
  • 模板编译
  • 构造数据
  • 填充模板数据

5、模板工具Jaspersoft Studio

<1>、概述

Jaspersoft Studio是JasperReports库和JasperReports服务器的基于Eclipse的报告设计器; 它可以作为Eclipse插件或作为独立的应用程序使用。Jaspersoft Studio允许您创建包含图表,图像,子报表,交叉表等的复杂布局。可以通过JDBC,TableModels,JavaBeans,XML,Hibernate,大数据(如Hive),CSV,XML / A以及自定义来源等各种来源访问数据,然后将报告发布为PDF,RTF, XML,XLS,CSV,HTML,XHTML,文本,DOCX或OpenOffice。

Jaspersoft Studio 是一个可视化的报表设计工具,使用该软件可以方便地对报表进行可视化的设计,设计结果为格式.jrxml 的 XML 文件,并且可以把.jrxml 文件编译成.jasper 格式文件方便 JasperReport 报表引擎解析、显示。

<2>、安装配置

到JasperReport官网下载https://community.jaspersoft.com/community-download

下载 Library Jar包(传统导入jar包工程需下载)和模板设计器Jaspersoft studio。并安装Jaspersoft studio,安装的过程比较简单,一直下一步直至安装成功即可。

<3>、面板介绍

  • Report editing area (主编辑区域)中,您直观地通过拖动,定位,对齐和通过 Designer palette(设计器调色板)对报表元素调整大小。JasperSoft Studio 有一个多标签编辑器,Design,Source 和 Preview:
    Design tab:当你打开一个报告文件,它允许您以图形方式创建报表选中
    Source tab: 包含用于报表的 JRXML 源代码。
    Preview tab: 允许在选择数据源和输出格式后,运行报表预览。
  • Repository Explorer view:包含 JasperServer 生成的连接和可用的数据适配器列表
  • Project Explorer view:包含 JasperReports 的工程项目清单
  • Outline view:在大纲视图中显示了一个树的形式的方式报告的完整结构。
  • Properties view:通常是任何基于 Eclipse 的产品/插件的基础之一。它通常被填充与实际所选元素的属性的信息。这就是这样,当你从主设计区域(即:一个文本字段)选择一个报表元素或从大纲,视图显示了它的信息。其中一些属性可以是只读的,但大部分都是可编辑的,对其进行修改,通常会通知更改绘制的元素(如:元素的宽度或高度)。
  • Problems view:显示的问题和错误,例如可以阻断报告的正确的编译。
  • Report state summary 提供了有关在报表编译/填充/执行统计用户有用的信息。错误会显示在这里

<4>、基本使用

(1)、模板制作

1、打开Jaspersoft Studio ,新建一个project, 步骤: File -> New -> Project-> JasperReports Project
2、新建一个Jasper Report模板,在 Stidio的左下方Project Explorer 找到刚才新建的Project (我这里新建的是DemoReport),步骤:项目右键 -> New -> Jasper Report
3、选择 Blank A4 (A4纸大小的模板),然后 Next 命名为DemoReport1.jrxml.

如图所示,报表模板被垂直的分层,每一个部分都是一个Band,每一个Band的特点不同:

  • Title(标题):只在整个报表的第一页的最上端显示。只在第一页显示,其他页面均不显示。
  • Page Header(页头):在整个报表中每一页都会显示。在第一页中,出现的位置在 Title Band的下面。在除了第一页的其他页面中Page Header 的内容均在页面的最上端显示。
  • Page Footer(页脚):在整个报表中每一页都会显示。显示在页面的最下端。一般用来显示页码。
  • Detail 1(详细):报表内容,每一页都会显示。
  • Column Header(列头):Detail中打印的是一张表的话,这Column Header就是表中列的列头。
  • Column Footer(列脚):Detail中打印的是一张表的话,这Column Footer就是表中列的列脚。
  • Summary(统计):表格的合计段,出现在整个报表的最后一页中,在Detail 1 Band后面。主要是用来做报表的合计显示。
(2)、编译模板

右键单机模板文件 -> compile Report 对模板进行编译,生成.jasper文件

(3)、整合工程

1、新建SpringBoot工程,引入相关依赖

  <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>net.sf.jasperreports</groupId><artifactId>jasperreports</artifactId><version>6.5.0</version></dependency><dependency><groupId>org.olap4j</groupId><artifactId>olap4j</artifactId><version>1.2.0</version></dependency><dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.0.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies>

2、配置application.yml

server:port: 8181
#spring配置
spring:#1.应用配置application:name: jasper-springboot #指定服务名#2.数据库连接池datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/ihrm?useUnicode=true&characterEncoding=utf8username: xxxxpassword: xxxx

3、创建启动类

package cn.itcast;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication(scanBasePackages = "cn.itcast")
public class JasperApplication {/*** 启动方法*/public static void main(String[] args) {SpringApplication.run(JasperApplication.class,args);}
}

4、在resources的创建templates目录并导入生成的.jasper文件
5、编写Controller

package cn.itcast.controller;import net.sf.jasperreports.engine.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;@RestController
public class JasperController {@GetMapping("/testJasper")public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {//1.引入jasper文件Resource resource = new ClassPathResource("templates/test.jasper");FileInputStream fis = new FileInputStream(resource.getFile());//2.创建JasperPrint,向jasper文件中填充数据ServletOutputStream os = response.getOutputStream();try {/*** fis                  : jasper文件输入流* new HashMap          :向模板中输入的参数* JasperDataSource     :数据源(和数据库数据源不同)*              填充模板的数据来源(connection,javaBean,Map)*              填充空数据来源:JREmptyDataSource*/JasperPrint print = JasperFillManager.fillReport(fis, new HashMap<>(),new JREmptyDataSource());//3.将JasperPrint以PDF的形式输出JasperExportManager.exportReportToPdfStream(print,os);} catch (JRException e) {e.printStackTrace();}finally {os.flush();}}
}
(4)、中文处理

这时候我们预览我们编写文件的效果,发现所有的中文部分全部没有显示出来,这时候我们可以编写插件进行处理这个问题。
1、设计阶段需要指定中文样式

2、手动指定中文字体的形式解决中文不现实

  • 在resources下创建net.sf.jasperreports.extension.registry.factory.simple.font.families配置文件
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.lobstertwo=stsong/fonts.xml
  • 在resources目录下创建stsong文件夹并添加fonts.xml
<?xml version="1.0" encoding="UTF-8"?><fontFamilies><!--<fontFamily name="Lobster Two">--><!--<normal>lobstertwo/LobsterTwo-Regular.otf</normal>--><!--<bold>lobstertwo/LobsterTwo-Bold.otf</bold>--><!--<italic>lobstertwo/LobsterTwo-Italic.otf</italic>--><!--<boldItalic>lobstertwo/LobsterTwo-BoldItalic.otf</boldItalic>--><!--<pdfEncoding>Identity-H</pdfEncoding>--><!--<pdfEmbedded>true</pdfEmbedded>--><!--<!–--><!--<exportFonts>--><!--<export key="net.sf.jasperreports.html">'Lobster Two', 'Times New Roman', Times, serif</export>--><!--</exportFonts>--><!--–>--><!--</fontFamily>--><fontFamily name="华文宋体"><normal>stsong/stsong.TTF</normal><bold>stsong/stsong.TTF</bold><italic>stsong/stsong.TTF</italic><boldItalic>stsong/stsong.TTF</boldItalic><pdfEncoding>Identity-H</pdfEncoding><pdfEmbedded>true</pdfEmbedded><exportFonts><export key="net.sf.jasperreports.html">'华文宋体', Arial, Helvetica, sans-serif</export><export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sans-serif</export></exportFonts><!--<locales><locale>en_US</locale><locale>de_DE</locale></locales>--></fontFamily>
</fontFamilies>
  • 在resources目录下引入字体库stsong.TTF

前后端分离微服务管理系统项目实战SaaS-HRM项目(九)——文件上传与PDF报表入门相关推荐

  1. iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门

    iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 文章目录 iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 PDF报表入门 3 ...

  2. 前后端分离微服务管理系统项目实战SaaS-HRM项目(二)——数据库设计与前端框架

    文章目录 二.数据库设计与前端框架 1.多租户SaaS平台的数据库方案 <1>.多租户概述 <2>.需求分析 <3>.多租户的数据库方案分析 (1).独立数据库 ( ...

  3. 若依前后端分离/微服务版怎样构造免密链接实现其他系统免登录访问

    场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客 上面在搭建起来前后端分离版的项目 ...

  4. 前后端分离微服务架构如何设计?

    一.职责划分 前端 前端工作专注业务的页面呈现,非常注重用户体验度,也是与各种角色打交道最多的. 比如: 前端开发人员会经常与产品经理或者客户讨论页面样式.视觉效果,页面布局等各种页面渲染效果 前端开 ...

  5. java版b2b2c多商家入驻微信小程序商城源码Spring Cloud+Spring Boot+mybatis+security+uniapp+直播带货+VR全景+前后端分离微服务商城源码

    1. 涉及平台 平台管理.商家端(PC端.手机端).买家平台(H5/公众号.小程序.APP端(IOS/Android).微服务平台(业务服务.系统服务.中间件服务) 2. 核心架构 Spring Cl ...

  6. Spring Boot项目实战之aliyunOss对象储存#文件上传接口实现(代码齐全)

    项目环境:   开发工具:IDEA(jdk1.8)   模块类型:Mavan项目   OSS版本:2.8.3   开发者文档链接:https://help.aliyun.com/document_de ...

  7. 数风流人物还看今朝|前后端分离微服务项目常用中间件以及指令

    日常积累 1.常用集成开发环境(IDE) 1.1.IDEA(后端) 1.2.VSCode(前端) 2.常用中间件 2.1 .redis及其常用指令 2.1.1.启动redis服务(器) 2.1.2.关 ...

  8. 【微服务|openfeign】使用openfeign远程调用文件上传接口

    文章目录 服务提供者-文件上传接口 FeignClient 消费者-通过FeignClient调用文件上传接口 服务提供者-文件上传接口 @PostMapping("/saveFile&qu ...

  9. 讲解开源项目:一步步跑起来个 Java 前后端分离的人力资源管理系统

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行项目,本示例是在 Windows 操作系统下演示. 本文作者:HelloGitHub-秦人 大家好!这里是 HelloGitHub 推出 ...

最新文章

  1. 如何使用OpenCV和Socket进行视频聊天?
  2. 宝贝,来,讲讲spring事务有哪些坑?
  3. [Classic] 日文版《出师表》
  4. 改善深层神经网络:超参数调整、正则化以及优化——2.3指数加权平均
  5. 万字长文!搞定逃不脱的 DNS 面试题
  6. linux iconv命令详解,iconv命令
  7. 微信公众号 语音转文字api_快速上手——微信公众号开发接入
  8. Android App 架构设计
  9. font-family 字体及各大主流网站对比
  10. 前端轻量级的toolTip插件-Tippy.js
  11. 高中信息技术课程标准读后感
  12. 计算机上显示找不到无线网络连接,笔记本没有无线网络连接怎么办 解决方法介绍【图解】...
  13. 8. 数仓开发之 DIM 层
  14. VSCode RemoteSSH 过程试图写入的管道不存在问题 解决
  15. React Or Vue
  16. 用平面图片制作3D模型【3DsMax】
  17. 概率论及概率图模型基础
  18. idea批量重命名(快捷键+全部替换两种方式)
  19. 转:作为一个HR,说说应届生及一两年往届生的注意情况。
  20. (转)Asterisk模拟线FXO的主叫号码识别(来电显示)

热门文章

  1. 电机专用SVPWM算法实现
  2. InstallShield Limited Edtion for VS2015
  3. !!! 格式塔原理及应用
  4. java encodeuricomponent 编码_encodeURIComponent编码与解码
  5. AutoCAD2014激活码不可用或失败问题解决
  6. 在Windows10操作系统下安装Ubuntu20.04 LTS,实现双系统
  7. 《超预测》菲利普•泰洛克 epub+mobi+azw3
  8. 2010年最佳免费英文字体
  9. LNK110:无法打开文件“opencv_world410d.lib”
  10. [018]HackerRank系列 | Shell遍历某个字符串多种用法