One, foreword
Things like this, the small company, before a function need to sign for a series of operations, so we introduced a sign on the signing of the tripartite platform -, but there is one point which may be embarrassing is that it does not support preview of the contract on the browser and the attachments, we want is to need to splice accessories shown in the main contract documents together, But it didn’t, so we had a requirements meeting…
The product said, we want to make an online contract signing function, which does not rely on the third party to complete, can preview and download the contract on the browser, small farmer, can you do it?
Once I listen to, well, this is a bit difficult, I need time, do not so good, we access to the third party is not fully completed before the browser preview function, the equivalent of one and the third party we do the same thing, but also that is compatible with more features than it is not so good to do (do) is really not so good, and also didn’t do before, There is no bottom in my heart.
The product said, there is no way (you have to do it or not), it is required by the leader (you can only do what is required above), would you please see how long it takes to complete these functions?
So I had to bite the bullet, so I gave it a reasonable amount of time, and then I started studying,What is happy Planet, if you want to know, then I can show you“, what?? Wait a minute. We’re off. Come back, come back.
Two, then I will take you to study
Study what? What is happy planet [manual dog head], cough, brainwashing, please stop your stupid * behavior immediately.
We know that if you want to operate the PDF (because signing contracts are generally used in PDF, comrades for you to solve your doubts, applause can be heard), so generally useIText (PDF Manipulation Library)
.Operation class library??What’s the matter with you?
We usually use Adobe tools to design forms and iText for content manipulation, and that’s what we’re going to talk about today. Now that we know what to use, what are our requirements? Work friends ever feel very terrible, “” we talk about demand, first of all need to implement is by PDF template fill our corresponding after party b’s basic data, generate PDF files, and then the database specific data splicing together in PDF, through a after party b has signed, and then make the contract for effective operation! Can be previewed and downloaded.
Demands is such a, listen to is not difficult to, mainly before didn’t do it, don’t mind if only one keeps the color, but after finish, have to call himself is a genius, I’m really clever, remind of small farmers from practice is made of PDF, now work so long or in PDF, drift (cao) is bright (Dan), then do bai, who afraid who ah!
Adobe tools
First of all, if you want to fill the content in the PDF template, you need to use Adobe Acrobat Peo DC
Download address:
Link: pan.baidu.com/s/1JdeKr7-a…
Extraction code: 6H0I
1. Open the PDF file
When we download wellAdobe Acrobat Peo DC
After, use it to open the PDF file and clickTo prepare the form
2. Add a text field
Click Add Text field
3. Fill in the variable name
This variable name is the parameter that we populate the data with, and it has to correspond one to one
4. After filling in, see the following
3. Start scheduling
Don’t worry guys, the project is ready for you. The project address is github.com/muxiaonong/…
The jar file:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5. 5</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>7.115.</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2. 0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> <! -- Itext generates word documents Lowagie </groupId> <artifactId> itext-rtf </artifactId> <version>2.14.</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.22.</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Copy the code
Generate files and splice product data from PDF templates
/** * Generate PDF files from the PDF template *@return* /
@GetMapping("generatePdf")
public String generatePdf(a) throws Exception{
// File file = ResourceUtils.getFile("classpath:"+SAVE_PATH);
File pdfFile = new File(ResourceUtils.getURL("classpath:").getPath()+SAVE_PATH);
try {
PdfReader pdfReader;
PdfStamper pdfStamper;
ByteArrayOutputStream baos;
Document document = new Document();
//
PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document,
new FileOutputStream(pdfFile));
document.open();
File file = ResourceUtils.getFile("classpath:"+templatePath);
pdfReader = new PdfReader(file.getPath());
int n = pdfReader.getNumberOfPages();
log.info("Pages:"+n);
baos = new ByteArrayOutputStream();
pdfStamper = new PdfStamper(pdfReader, baos);
for(int i = 1; i <= n; i++) {
AcroFields acroFields = pdfStamper.getAcroFields();
//key statement 1
acroFields.setGenerateAppearances(true);
//acroFields.setExtraMargin(5, 5);
acroFields.setField("customerAddress".Building 1, Lane 520, Tianzi Road, Pudong New Area, Shanghai);
acroFields.setField("customerCompanyName".Shanghai Baidu Co., LTD.);
acroFields.setField("customerName"."Zhang");
acroFields.setField("customerPhone"."15216667777");
acroFields.setField("customerMail"."[email protected]");
acroFields.setField("vendorAddress".182 Shiver Road, Pudong New Area, Shanghai);
acroFields.setField("vendorCompanyName"."Mu Xiao Nong Science and Technology Co., LTD");
acroFields.setField("vendorName"."Fifty");
acroFields.setField("vendorPhone"."15688886666");
acroFields.setField("vendorMail"."[email protected]");
acroFields.setField("effectiveStartTime".May 25, 2021);
acroFields.setField("effectiveEndTime"."25 May 2022");
//true indicates that the generated PDF file is not editable
pdfStamper.setFormFlattening(true);
pdfStamper.close();
pdfReader = new PdfReader(baos.toByteArray());
pdfSmartCopy.addPage(pdfSmartCopy.getImportedPage(pdfReader, i));
pdfSmartCopy.freeReader(pdfReader);
pdfReader.close();
}
pdfReader.close();
document.close();
} catch(DocumentException dex) {
dex.printStackTrace();
} catch(IOException ex) {
ex.printStackTrace();
}
// Create a PDF file
createPdf();
File file3 = new File(ResourceUtils.getURL("classpath:").getPath()+TEMP_PATH);
File file1 = new File(ResourceUtils.getURL("classpath:").getPath()+outputFileName);
List<File> files = new ArrayList<>();
files.add(pdfFile);
files.add(file3);
try {
PdfUtil pdfUtil = new PdfUtil();
pdfUtil.mergeFileToPDF(files,file1);
} catch (Exception e) {
e.printStackTrace();
}
// If you are uploading files to the file server, this is where you can upload files
// String url = fileServer.uploadPdf(File2byte(file1));
// Delete the total file
// Do not delete it if it is your local preview
// if(file1.exists()){
// file1.delete();
/ /}
// Delete the template file
if(pdfFile.exists()){
System.gc();
pdfFile.delete();
}
// Delete the product file
if(file3.exists()){
file3.delete();
}
return "success";
}
Copy the code
Create PDF attachment information to splice into the main file:
/** * Create PDF attachment information */
public static void createPdf(a) {
Document doc = null;
try {
doc = new Document();
PdfWriter.getInstance(doc, new FileOutputStream(ResourceUtils.getURL("classpath:").getPath()+TEMP_PATH));
doc.open();
BaseFont bfChi = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontChi = new Font(bfChi, 8, Font.NORMAL);
PdfPTable table = new PdfPTable(5);
Font fontTitle = new Font(bfChi, 15, Font.NORMAL);
PdfPCell cell = new PdfPCell(new Paragraph("* Freight * Transport Service Agreement - Appendix 1 Transport Fee Quotation",fontTitle));
cell.setColspan(5);
table.addCell(cell);
// ""
table.addCell(new Paragraph("Serial number",fontChi));
table.addCell(new Paragraph("Category",fontChi));
table.addCell(new Paragraph("Name",fontChi));
table.addCell(new Paragraph("Method of calculation",fontChi));
table.addCell(new Paragraph("Rate",fontChi));
table.addCell(new Paragraph("1",fontChi));
table.addCell(new Paragraph("Freight",fontChi));
table.addCell(new Paragraph("The rate of 1.0",fontChi));
table.addCell(new Paragraph("Count",fontChi));
table.addCell(new Paragraph("0~1 million -5.7%, upper limit: 500 YUAN, lower limit: 20 yuan",fontChi));
table.addCell(new Paragraph("2",fontChi));
table.addCell(new Paragraph("Freight",fontChi));
table.addCell(new Paragraph("The rate of 1.0",fontChi));
table.addCell(new Paragraph("Down",fontChi));
table.addCell(new Paragraph("1 million to 2 million -5.6%, no upper limit, no lower limit",fontChi));
table.addCell(new Paragraph("3",fontChi));
table.addCell(new Paragraph("Freight",fontChi));
table.addCell(new Paragraph("The rate of 1.0",fontChi));
table.addCell(new Paragraph("Count",fontChi));
table.addCell(new Paragraph("2 million to 3 million -5.5%, no upper or lower limit.",fontChi));
doc.add(table);
// doc.add(new Paragraph("Hello World, look at the Chinese support not........ aaaaaaaaaaaaaaaaa",fontChi));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{ doc.close(); }}Copy the code
Contract Signing:
/** * Sign the contract *@return
* @throws IOException
* @throws DocumentException
*/
@GetMapping("addContent")
public String addContent(a) throws IOException, DocumentException {
BaseFont baseFont = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font font = new Font(baseFont);
// This can be a local address or a file address on the server
PdfReader reader = new PdfReader(ResourceUtils.getURL("classpath:").getPath()+outputFileName);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(ResourceUtils.getURL("classpath:").getPath()+endPdf));
//
PdfContentByte over = stamper.getOverContent(1);
ColumnText columnText = new ColumnText(over);
PdfContentByte over1 = stamper.getOverContent(1);
ColumnText columnText1 = new ColumnText(over1);
PdfContentByte over2 = stamper.getOverContent(1);
ColumnText columnText2 = new ColumnText(over2);
PdfContentByte over3 = stamper.getOverContent(1);
ColumnText columnText3 = new ColumnText(over3);
// The smallest LLX and urx values determine the distance from the left, and the largest lly and ury values determine the distance from the bottom
// LLX left aligned
// lly on alignment
/ / urx broadband
/ / ury height
columnText.setSimpleColumn(29.117.221.16);
Paragraph elements = new Paragraph(0.new Chunk(Shanghai Yizhan Supply Chain Co., LTD.));
columnText1.setSimpleColumn(26.75.221.16);
Paragraph elements1 = new Paragraph(0.new Chunk("March 03, 2021"));
columnText2.setSimpleColumn(800.120.200.16);
Paragraph elements2 = new Paragraph(0.new Chunk(Wuhu Branch of Yihui (Jiangsu) Supply Chain Management Co., LTD.));
columnText3.setSimpleColumn(800.74.181.16);
Paragraph elements3 = new Paragraph(0.new Chunk("03 March 2022"));
// Acrofields.setfield ("customerSigntime", "mar 03, 2021 ");
// Acrofields. setField("vendorSigntime", "03/09, 2021 ");
// Set the font, if you do not set the added Chinese will not be displayed
elements.setFont(font);
columnText.addElement(elements);
columnText.go();
elements1.setFont(font);
columnText1.addElement(elements1);
columnText1.go();
elements2.setFont(font);
columnText2.addElement(elements2);
columnText2.go();
elements3.setFont(font);
columnText3.addElement(elements3);
columnText3.go();
stamper.close();
File tempFile = new File(ResourceUtils.getURL("classpath:").getPath()+"Sign test.pdf");
// If you want to upload to the server, fill in the server address
// String url = fileServer.uploadPdf(File2byte(tempFile));
/ / the info (" url: "+ url);
// Delete the information after uploading to the server
// Do not delete locally, otherwise there is no file
// if(tempFile.exists()){
// tempFile.delete();
/ /}
return "success";
}
Copy the code
PDF tools:
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.List;
/*** * PDF related operations *@author mxn
*/
@Slf4j
@Component
public class PdfUtil {
/** * Merge PDF files *@paramFiles File list *@paramOutput Output PDF file */
public void mergeFileToPDF(List<File> files, File output) {
Document document = null;
PdfCopy copy = null;
OutputStream os = null;
try {
os = new FileOutputStream(output);
document = new Document();
copy = new PdfCopy(document, os);
document.open();
for (File file : files) {
if(! file.exists()) {continue;
}
String fileName = file.getName();
if (fileName.endsWith(".pdf")) {
PdfContentByte cb = copy.getDirectContent();
PdfOutline root = cb.getRootOutline();
new PdfOutline(root, new PdfDestination(PdfDestination.XYZ), fileName
.substring(0, fileName.lastIndexOf(".")));
// Do not use reader to maintain files, otherwise not delete files, always occupied
try (InputStream is = new FileInputStream(file)) {
PdfReader reader = new PdfReader(is);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) { document.newPage(); PdfImportedPage page = copy.getImportedPage(reader, j); copy.addPage(page); }}catch(Exception e) {
log.warn("error to close file : {}" + file.getCanonicalPath(), e);
// e.printStackTrace();}}else {
log.warn("file may not be merged to pdf. name:"+ file.getCanonicalPath()); }}}catch (Exception e) {
e.printStackTrace();
} finally {
if(document ! =null) {
document.close();
}
if(copy ! =null) {
copy.close();
}
if(os ! =null) { IOUtils.closeQuietly(os); }}}/** * convert file to byte array *@param file
* @return* * * /
public static byte[] File2byte(File file){
byte[] buffer = null;
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while((n = fis.read(b)) ! = -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
returnbuffer; }}Copy the code
demo
When we finished writing, came to the most critical place, the test, there is a little excitement in the heart, there should be no BUG
First we enter http://localhost:8080/generatePdf, generate filling template, generate new PDF files and merge files, generated after we will see this file in class project directory
If you open our file, you can see the corresponding data information. If you get there, you can just check the last step to sign the contract
Here if you can put the sign information, fill in the position to the contract is signed, accomplished that we can say, we signed the input address, http://localhost:8080/addContent, when we see the sign test directory. When we get the PDF, we’re done
We can see that the corresponding signature information has been added, except that there is no third party authentication, all the functions are available, which is excellent!
This time I inevitably think of, Li Bai that sentence“When I go out laughing with my face up to the sky, I am not the Penghao people.”, the weather cleared up, the rain stopped, I think I went again, I have been associated with the product little sister worship of the small eyes, charm shine, please don’t be infatuated with elder brother! Don’t just drink. Eat a la carte. A few dishes
conclusion
If this function can be used normally in the project of the company, the above is the detailed code and description of this function. If you have any questions or are also doing this function, you can leave a message and the small farmer will reply as soon as he sees it
If you feel good, remember a key three link ~
Over 100 likes, I’ll write my next one even when I’m pregnant with twins
I am a small farmer, afraid of what infinite truth, further have further joy, everyone come on!