文章目录
CrystalReport依赖下载
1.依赖下载
SAP网站是国外网站,是全英文的,网站资源很丰富,找个CrytalReport都费劲。你可以通过下面的地址下载:
SAP Crystal Reports, developer version for Microsoft Visual Studio: Updates & Runtime Downloads
或者可通过网盘下载链接下载相关jar依赖,直接放到maven仓库下的\com目录下解压
链接: https://pan.baidu.com/s/1CVsRKDw67sQ0brje9f3uVQ 提取码: qzav
2.水晶报表设计器下载
我用的水晶报表设计器是2008版本,有需要的可通过以下链接下载破解版
链接: https://pan.baidu.com/s/11mxiXsHg5yON7N0mwrctvA 提取码: ibki
下载后傻瓜式的安装就可以了,破解安装后,打开的界面如下
实现报表打印和动态图片导入流程
1.数据准备
书写一个wmGrnDetail.txt的数据源,内容如下
labelNum,lineNum,qty,uom,spaceCode,grnNum,suppLabelNum,suppCode,suppName,weight,weightUnit,materialCode,materialName,imageURL
2.生成mytest.rpt文件
使用水晶报表设计器设计wmGrnDetail.rpt文件
(1)新建空白报表文件
在弹窗中选择mytest.txt文件,点击“>”符号,mytest.txt文件会跑到右边,点击确定
导入后如下
(2)设计水晶报表
设计好报表的样式,把数据源的字段拖曳过来即可,这里主要详细介绍一下动态图片的配置。
(3)添加动态图片
点击插入->图片,选中任意图片放到指定位置
注意,这里图片是作用是告诉程序,图片应该放到哪个位置、图片的长宽是多少,程序会根据URL把后台返回的动态图片替换该静态图片。
添加静态图片到指定位置后(我的图片放到右下角),报表样式如下:
右键单击图片,选择设置图形格式
设计器引入的是静态图片,需要为图片指定动态的URL,URL由后端设置,这样就可以实现动态图片的功能了。
在新弹窗中,选择"报表字段",在字段列表中找到封装了动态URL的字段,双击后,会自动带出到下方的输入框中,选择"保存并关闭"
最后导出报表,重命名为wmGrnDetail.rpt
3.导入依赖
将下载下来的crystal.rar文件在maven下的/com目录下解压后,需要在项目中加入以下maven依赖。
<dependency>
<groupId>com.crystal</groupId>
<artifactId>azalea-ufl</artifactId>
<version>1.0</version>
</dependency>
<!--水晶报表公共包-->
<dependency>
<groupId>com.crystal</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.2</version>
</dependency>
<!--水晶报表多语言支持-->
<dependency>
<groupId>com.crystal</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<!--水晶报表日志包-->
<dependency>
<groupId>com.crystal</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>CrystalCommon2</artifactId>
<version>1.0</version>
</dependency>
<!--水晶报表运行相关包-->
<dependency>
<groupId>com.crystal</groupId>
<artifactId>CrystalReportsRuntime</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>cvom</artifactId>
<version>1.0</version>
</dependency>
<!--水晶报表数据库连接包-->
<dependency>
<groupId>com.crystal</groupId>
<artifactId>DatabaseConnectors</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>icu4j</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>jai_imageio</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>JDBInterface</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>jrcerom</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>keycodeDecoder</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>log4j</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>logging</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>pfjgraphics</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>QueryBuilder</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>tc-sec-csi</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>webreporting</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>webreporting-jsf</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>XMLConnector</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.crystal</groupId>
<artifactId>xpp3</artifactId>
<version>1.0</version>
</dependency>
3.创建相关类
创建实体类:WmGrnDetail.java
@Getter
@Setter
@Accessors(chain = true)
@ApiModel(value = "WmGrnDetailDto对象", description = "收货标签表")
public class WmGrnDetailDto extends BaseDto {
/**
* 主表Id(明细表)
*/
@ApiModelProperty("主表Id(明细表)")
private String grnGroupDetId;
/**
* 标签号
*/
@ApiModelProperty("标签号")
private String labelNum;
/**
* 行号
*/
@ApiModelProperty("行号")
private Integer lineNum;
/**
* 数量(标签对应入库数量)
*/
@ApiModelProperty("数量(标签对应入库数量)")
private BigDecimal qty;
/**
* 仓位
*/
@ApiModelProperty("仓位")
private String spaceCode;
/**
* 收货单号
*/
@ApiModelProperty("收货单号")
private String grnNum;
/**
* 供应商批次
*/
@ApiModelProperty("供应商批次")
private String suppLabelNum;
/**
* 删除人id
*/
@ApiModelProperty("删除人id")
private String deleteUserId;
/**
* 删除时间
*/
@ApiModelProperty("删除时间")
private LocalDateTime deleteTime;
/**
* 过账人id
*/
@ApiModelProperty("过账人id")
private String postUserId;
/**
* 过账时间
*/
@ApiModelProperty("过账时间")
private LocalDateTime postTime;
/**
* 仓位名称
*/
@ApiModelProperty("仓位名称")
private String spaceName;
/**
* 仓位类型
*/
@ApiModelProperty("仓位类型")
private String spaceType;
/**
* 仓库类型
*/
@ApiModelProperty("仓库类型")
private String warehouseType;
/**
* 仓库名称
*/
@ApiModelProperty("仓库名称")
private String warehouseName;
@ApiModelProperty("租户id")
private Long tenantId;
/**
* 创建人id
*/
@ApiModelProperty("创建人id")
private String createUserId;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("最后更新人Id")
private String lastUpdateUserId;
@ApiModelProperty("最后更新时间")
private LocalDateTime lastUpdateTime;
@ApiModelProperty("物料ID")
private Long materialId;
@ApiModelProperty("物料编码")
private String materialCode;
@ApiModelProperty("物料名称")
private String materialName;
@ApiModelProperty("重量")
private BigDecimal weight;
@ApiModelProperty("重量单位")
private String weightUnit;
/**
* 供应商编码
*/
@ApiModelProperty("供应商编码")
private String suppCode;
/**
* 供应商名称
*/
@ApiModelProperty("供应商名称")
private String suppName;
@ApiModelProperty("单位")
private String uom;
@ApiModelProperty("图片路径")
private String imageURL;
}
二维码生成工具类:QRCodeUtil.java类
import com.csmart.warehouse.utils.Commvar;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.beans.factory.annotation.Value;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class QRCodeUtil {
private static final String CHARSET = "UTF-8";
private static final String FORMAT_NAME = "png";
// 二维码尺寸
private static final int QRCODE_SIZE = 200;
@Value("${rpt.temp_directory}")
private String tempDirectory;
/**
* 生成二维码
* @param content URL地址
* @param filePath 文件全路径
* @return boolean
*/
public static boolean createQRCode(String content, String filePath){
File file = new File(filePath);
BufferedImage bufferedImage;
//生成图片
try {
bufferedImage = createImage(content);
} catch (WriterException e) {
throw new RuntimeException(e);
}
//保存文件
try {
return ImageIO.write(bufferedImage, FORMAT_NAME, file);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 创建二维码图片
*/
private static BufferedImage createImage(String content) throws WriterException {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
return image;
}
/**
* 根据文本内容生成二维码
* @param content 二维码内容
* @return 返回文件路径
*/
public static String generalImage(String content){
String directorypath = System.getProperty("user.dir") + File.separator + Commvar.COMMOM.RPT_TEMP;
File directory = new File(directorypath);
// 判断路径是否存在
if (!directory.exists()) {
// 路径不存在,进行创建
if (!directory.mkdirs()){
String errMsg = "目录:%s 创建失败";
throw new RuntimeException(String.format(errMsg,directorypath));
}
}
//获取文件路径
String path = directorypath+File.separator+content+ Commvar.COMMOM.SUFF_IMAGE;
createQRCode(content,path);
return path;
}
水晶报表控制类:QRCodeUtil.java类
import com.crystaldecisions.sdk.occa.report.application.ReportClientDocument;
import com.csmart.masterdata.util.CRJavaHelper;
import com.csmart.masterdata.util.QRCodeUtil;
import com.csmart.warehouse.dto.WmGrnDetailDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "水晶报表控制类")
@RestController
@RequestMapping("/api/cry")
public class CrystalReportController {
@ApiOperation(value = "打印")
@GetMapping("print/{id}")
public void wmGrnMasterPrintLabel(HttpServletResponse response, @PathVariable long id) {
try {
String imageURL = "";
String rptFileName = "./crystal/wmGrnDetail.rpt";
//创建临时的rpt文件存放目录
String tempDirectory = "/data/rpt-temp/";
List<WmGrnDetailDto> list = new ArrayList<>();
//生成临时文件
File rptTempFile = CRJavaHelper.getRptTempFile(rptFileName,tempDirectory);
//打开报表
ReportClientDocument reportClientDoc = new ReportClientDocument();
// 获取报表的 ReportDefController 对象
reportClientDoc.open(rptTempFile.getAbsolutePath(), 0);
//数据绑定
WmGrnDetailDto dto = new WmGrnDetailDto();
dto.setSuppName("产商名称");
dto.setMaterialCode("物料编码");
dto.setMaterialName("物料名称");
//传参是二维码的内容,返回二维码图片的地址。
imageURL = QRCodeUtil.generalImage("www.baidu.com");
dto.setImageURL(imageURL);
list.add(dto);
//数据绑定
CRJavaHelper.passPOJO(reportClientDoc, list,
WmGrnDetailDto.class.getCanonicalName(), "wmGrnDetail_txt", "");
//输出成pdf
CRJavaHelper.exportPDF(reportClientDoc,response,false);
//关闭文档及删除临时文件
try {
reportClientDoc.close();
}catch (Exception e){
e.printStackTrace();
}
try {
rptTempFile.delete();
}catch (Exception e){
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
使用postman工具模拟请求,输出报表
扫码二维码的内容,可以看出得到的是百度的地址:https://www.baidu.com/,可以看出,动态图片功能已经实现了。