Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.
The result of the previous article is this
There are many functions in the report, you can make them according to your needs. Next, I’ll show you how to use it in a Java project. Will be implemented in the back and forth code.
Front-end code (here’s the Angular front-end, which I’m not very good at either) 1. page
<button type="button" class="btn btn-primary" (click) ="previewReport(prodProcessCabinetOrder)">preview</button>
<button type="button" class="btn btn-primary" (click) ="printReport(prodProcessCabinetOrder)">print</button>
<button type="button" class="btn btn-primary" (click) ="update(prodProcessCabinetOrder)">Modify the</button>// Some other code is omitted<div class="modal fade" id="pdfViewerModel" role="dialog" tabindex="1" aria-labelledby="pdfViewerModelLabel">
<div class="modal-dialog modal-lg" role="document" style="width: 60%">
<div class="modal-content">
<div class="modal-header">
<button type="button" (click) ="close()" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="pdfViewerModelLabel">Print preview</h4>
</div>
<div class="modal-body" style="height: 800px;">
<ng2-pdfjs-viewer #pdfViewerOnDemand></ng2-pdfjs-viewer>
</div>
</div>
</div>
</div>
Copy the code
2. The front-end needs to import PDF modules, which is not very understanding, not good at the front-end
import { PdfJsViewerModule } from 'ng2-pdfjs-viewer';
Copy the code
3. Angular has entity classes, just like backend code, but other front-end frameworks do not have entity classes.
export class ProdProcessCabinetOrder {
id: number;
orderNo: string;
orderType: string;
drawingNo: string;
productType: string;
customerNo: string;
customerName: string;
consignee: string;
consigneePhone: string;
consigneeAddr: string;
terminalCustomer: string;
documentMakerNo: string;
documentMakerName: string;
documentMakeDate: string;
deliveryDate: string;
orderStatus: number;
processCabinetDetails: ProdProcessCabinetDetail[];
downloadExceled: boolean;
grain: number;
processOrderRouting: ProcessOrderRouting;
refOrderNo: string;
}
Copy the code
4. Front-end implementation functionality (this is like Ajax or something)
@ViewChild('pdfViewerOnDemand', { static: false }) pdfViewerOnDemand;
previewReport(prodProcessCabinetOrder: ProdProcessCabinetOrder) {
let fileName = 'Cabinet Production Process Sheet' + prodProcessCabinetOrder.refOrderNo + '.pdf';// Assign a value to the filename
// Find the prodProcessCabinetOrder object based on its ID
this.prodProcessCabinetOrderService.getReportById(prodProcessCabinetOrder.id).subscribe(
res= > {
// The following attributes are assigned to the pdfViewerOnDemand attribute
this.pdfViewerOnDemand.pdfSrc = res;
this.pdfViewerOnDemand.downloadFileName = fileName;
this.pdfViewerOnDemand.refresh();
$('#pdfViewerModel').modal({
backdrop: 'static'.keyboard: false.show: true
});
},
error= > this.errorMessage = <any>error
);
}
// Print reports
printReport(prodProcessCabinetOrder: ProdProcessCabinetOrder) {
this.prodProcessCabinetOrderService.printReportById(prodProcessCabinetOrder.id).subscribe(
any= >{},error= > this.errorMessage = <any>error
);
}
// Close the report
close(){$('#pdfViewerModel').modal('hide');
}
Copy the code
Different from layui, Easyui and other front-end frameworks, ajax will be different (the idea can be as follows: find the object by ID, how to trigger its specific function, and pass the required parameters to the back-end).
Two: Compile file and the required file JRXML file, right click, select Compile Report
After the files are compiled, the generated Jasper files are put into the Java project
I put the compiled files in the Resources package, stsong is the font file and JasperReports_extension.properties is the configuration file for the report
In the report, I used a Chinese font
Fonts.xml code in stsong file:
<fontFamilies>
<fontFamily name="Song Style in Chinese">
<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">'Chinese Font style ', Arial, Helvetica, Sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'Chinese Font style ', Arial, Helvetica, Sans-serif</export>
</exportFonts>
</fontFamily>
</fontFamilies>
Copy the code
Stsong-ttf file (double-click to open it like this)
Jasperreports_extension. The properties file
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
Copy the code
As for the above mentioned documents, there are online, are downloaded down
Three: the back-end code (new JavaWeb project those will not be demonstrated) remember to import the relevant JAR package 1. Entity class
@Entity
public class ProdProcessCabinetOrder {
@Id
@GeneratedValue
private Integer id;
private String orderNo;
private String orderType;
private String drawingNo;
private String productType;
private String customerNo;
private String customerName;
private String consignee;
private String consigneePhone;
private String consigneeAddr;
private String terminalCustomer;
private String documentMakerNo;
private String documentMakerName;
private Date documentMakeDate;
private Date deliveryDate;
@ColumnDefault("0")
private int grain;
private int orderStatus;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "prod_process_cabinet_order_process_cabinet_details", joinColumns = @JoinColumn(name = "prod_process_cabinet_order_id"))
private List<ProdProcessCabinetDetail> processCabinetDetails;// This is a child object
private boolean downloadExceled;
@ManyToOne
private ProcessOrderRouting processOrderRouting;
@ColumnDefault("false")
private boolean done;
private String refOrderNo;
}
Copy the code
2. Child objects
@Embeddable
public class ProdProcessCabinetDetail {
private String cabinetComponentNo;
private String cabinetComponentName;
private float cabinetComponentWidth;
private float cabinetComponentHeight;
@ColumnDefault("0")
private float thick;
private int cabinetComponentQuantity;
private String cabinetComponentItemNo;
private String cabinetComponentItemName;
private float cabinetComponentItemWidth;
private float cabinetComponentItemHeight;
private String cabinetEdgeItemNo;
private String cabinetEdgeItemName;
private String cabinetEdgeItemNo2;
private String cabinetEdgeItemName2;
private int widthEdgeQty;
private int heightEdgeQty;
@ColumnDefault("0")
private float edge1ItemSize;
@ColumnDefault("0")
private float edge2ItemSize;
private String slot;
private String remark;
@ColumnDefault("false")
private boolean packinged;
}
Copy the code
3. The report class
public class ProdProcessCabinetReport {
private Integer index;
private String cabinetComponentName;
private float cabinetComponentWidth;
private float cabinetComponentHeight;
private float cabinetComponentItemWidth;
private float cabinetComponentItemHeight;
private int cabinetComponentQuantity;
private float thick;
private String cabinetComponentItemName;
private String cabinetEdgeItemName;
private String cabinetEdgeItemName2;
private String remark;
/ / omitted getters and setters
}
Copy the code
Note: I need more than one object here, so put the code out there. Depending on your situation, an entity class is fine
4. Service layer code:
@Override
public ResponseEntity<byte[]> getReportById(Integer id) {
ProdProcessCabinetOrder prodProcessCabinetOrder = this.getProdProcessCabinetOrder(id);// Find the ProdProcessCabinetOrder object based on its ID
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));// Report format
String pdfName = "Cabinet Production Process Sheet" + prodProcessCabinetOrder.getRefOrderNo() + ".pdf";// File name
headers.setContentDispositionFormData(pdfName, pdfName);// Call the HttpHeaders method
byte[] contents = buildPdfDocument(prodProcessCabinetOrder);// Specify the function
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
prodProcessCabinetOrder.setDownloadExceled(true);// Set the related properties
processCabinetOrderRepository.save(prodProcessCabinetOrder);/ / save
return response;
}
private byte[] buildPdfDocument(ProdProcessCabinetOrder prodProcessCabinetOrder) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
Resource resource = new ClassPathResource("jasperreport/productionprocess/cabinet/cabinet.jasper");// The path to the compiled file
FileInputStream fis = new FileInputStream(resource.getFile());
Resource subReportResource = new ClassPathResource(
"jasperreport/productionprocess/cabinet/cabinet_footer.jasper");// The path to the second compiled file
String footerSubReportPath = subReportResource.getFile().getPath();
fillReportData(prodProcessCabinetOrder, fis, os, footerSubReportPath);// Handle file specific functions
} catch (IOException | JRException e) {
e.printStackTrace();
}
return os.toByteArray();
}
private void fillReportData(ProdProcessCabinetOrder prodProcessCabinetOrder, FileInputStream fis, ByteArrayOutputStream os, String footerSubReportPath) throws JRException {
List<ProdProcessCabinetDetail> prodProcessCabinetDetails = prodProcessCabinetOrder.getProcessCabinetDetails();// Get the ProdProcessCabinetDetail, a child of the prodProcessCabinetOrder object
Map<String, Object> parameters = fillReportParametersData(prodProcessCabinetOrder, prodProcessCabinetDetails,
footerSubReportPath);// The method to generate the Parameters in the report from which the values are assigned
List<ProdProcessCabinetReport> reportFields = fillReportFieldsData(prodProcessCabinetDetails);// This is the Fields method, which corresponds to the Fields in the background report
JasperRunManager.runReportToPdfStream(fis, os, parameters, new JRBeanCollectionDataSource(reportFields));// Reporting tools provide a method, this method can be implemented on the web to learn some
}
// This method is the Parameters in the corresponding report, which is assigned to the report
private Map<String, Object> fillReportParametersData(ProdProcessCabinetOrder prodProcessCabinetOrder, List
prodProcessCabinetDetails, String footerSubReportPath)
{
String qrCodePic = QRCodeUtil.genQRCodePic(OrderType.PROCESS_CABINET_ORDER.getIndex(),
prodProcessCabinetOrder.getOrderNo(), prodProcessCabinetOrder.getRefOrderNo(), qrCodeFileProps);// This is the path to get the image
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("reportTitle"."Cabinet Production Process Sheet");
parameters.put("qrCodePic", qrCodePic);
parameters.put("refOrderNo", prodProcessCabinetOrder.getRefOrderNo());
parameters.put("orderType", prodProcessCabinetOrder.getOrderType());
parameters.put("productType", prodProcessCabinetOrder.getProductType());
parameters.put("drawingNo", prodProcessCabinetOrder.getDrawingNo());
parameters.put("deliveryDate", DateFormat.formatDate("yyyy-MM-dd", prodProcessCabinetOrder.getDeliveryDate()));
parameters.put("terminalCustomer", prodProcessCabinetOrder.getTerminalCustomer());
double sumComponItemsArea = prodProcessCabinetOrder.sumComponItemsArea();
parameters.put("sumComponItemsArea", (double) (Math.round(sumComponItemsArea * 100)) / 100);
parameters.put("sumQty", prodProcessCabinetOrder.sumQty());
parameters.put("customerName", prodProcessCabinetOrder.getCustomerName());
parameters.put("documentMakeDate", DateFormat.formatDate("yyyy-MM-dd", prodProcessCabinetOrder.getDocumentMakeDate()));
parameters.put("documentMakerName", prodProcessCabinetOrder.getDocumentMakerName());
parameters.put("cabinet_footer_report_path", footerSubReportPath);
return parameters;
}
// This method and the following method generate Fields data corresponding to the Fields of the report
private List<ProdProcessCabinetReport> fillReportFieldsData( List
prodProcessCabinetDetails)
{
List<ProdProcessCabinetReport> reportFields = new ArrayList<ProdProcessCabinetReport>();
if(prodProcessCabinetDetails ! =null && prodProcessCabinetDetails.size() > 0) {
int index = 1;
for(ProdProcessCabinetDetail detail : prodProcessCabinetDetails) { fillReportFieldData(detail, reportFields, index); index++; }}return reportFields;
}
// Get the Fields data
private void fillReportFieldData(ProdProcessCabinetDetail detail, List<ProdProcessCabinetReport> reportFields,
int index) {
ProdProcessCabinetReport processCabinetReport = new ProdProcessCabinetReport();
processCabinetReport.setIndex(index);
processCabinetReport.setCabinetComponentName(detail.getCabinetComponentName());
processCabinetReport.setCabinetComponentWidth(detail.getCabinetComponentWidth());
processCabinetReport.setCabinetComponentHeight(detail.getCabinetComponentHeight());
processCabinetReport.setCabinetComponentItemWidth(detail.getCabinetComponentItemWidth());
processCabinetReport.setCabinetComponentItemHeight(detail.getCabinetComponentItemHeight());
processCabinetReport.setCabinetComponentQuantity(detail.getCabinetComponentQuantity());
processCabinetReport.setThick(detail.getThick());
processCabinetReport.setCabinetComponentItemName(detail.getCabinetComponentItemName());
processCabinetReport.setCabinetEdgeItemName(detail.getCabinetEdgeItemName());
processCabinetReport.setCabinetEdgeItemName2(detail.getCabinetEdgeItemName2());
processCabinetReport.setRemark(detail.getRemark());
reportFields.add(processCabinetReport);
}
@Override
public void printReportById(Integer id) {
ProdProcessCabinetOrder processCabinetOrder = this.getProdProcessCabinetOrder(id);
byte[] pdfByte = this.buildPdfDocument(processCabinetOrder);
PdfPrintUtil pdfPrintUtil = new PdfPrintUtil();
pdfPrintUtil.printPdf(pdfByte, "# # # # # #");
}
Copy the code
Printing method
public class PdfPrintUtil {
public void printPdf(byte[] pdfByte, String printerName) {
PDDocument document = null;
try {
document = PDDocument.load(pdfByte);
PrinterJob job = setPrinterJonParas(document, printerName);
job.print();
} catch (IOException | PrinterException e) {
System.out.println("Error printing PDF file");
e.printStackTrace();
} finally {
if(document ! =null) {
try {
document.close();
} catch (IOException e) {
System.out.println("Error closing PDF-document"); e.printStackTrace(); }}}}/ * * * * *@param document
* @paramPrinterName * printerName *@returnIf not specified, find the default printer *@throws PrinterException
*/
private PrinterJob setPrinterJonParas(PDDocument document, String printerName) throws PrinterException {
// Set the paper and zoom
PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
PageFormat pageFormat = new PageFormat();
// Set the print direction (landscape)
pageFormat.setOrientation(PageFormat.LANDSCAPE);
// Set the paper property
pageFormat.setPaper(this.getPaper());
Book book = new Book();
book.append(pdfPrintable, pageFormat, document.getNumberOfPages());
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(this.getPrinter(printerName));
job.setPageable(book);
// Set the number of copies to print
job.setCopies(1);
return job;
}
private Paper getPaper(a) {
Paper paper = new Paper();
// Default is A4 paper, corresponding to the pixel width and height of 595,842
int width = 595;
int height = 842;
// Set the margin in pixels
int marginLeft = 0, marginRight = 0, marginTop = 0, marginBottom = 0;
paper.setSize(width, height);
paper.setImageableArea(marginLeft, marginTop, width - (marginLeft + marginRight),
height - (marginTop + marginBottom));
return paper;
}
private PrintService getPrinter(String printerName) {
DocFlavor psInFormat = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
/ / A4 paper
pras.add(MediaSizeName.ISO_A4);
/ / a single page
pras.add(Sides.ONE_SIDED);
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(psInFormat, pras);
PrintService myPrinter = null;
for (PrintService printService : printServices) {
System.out.println("Printer name" + printService.getName());
if (printService.getName().contains(printerName)) {
myPrinter = printService;
break; }}if (myPrinter == null) {
myPrinter = PrintServiceLookup.lookupDefaultPrintService();
}
returnmyPrinter; }}Copy the code
You can refer to the method I wrote, but not necessarily suitable. In summary, values are assigned to the corresponding report from the entity-class object
Reference effect:
Click preview to see the following effect
Printing is also available. Remember to connect the printer
More functions, which are not shown here.