在我最近的春季项目中,我需要从html页面生成pdf文件。我正在尝试使用WkhtmlToPdf
来完成此任务。但是我无法从html页面生成pdf文件。我搜索了许多有关WkhtmlToPdf
的项目和教程,但没有找到任何答案。我在这里发布我的代码。
这是我的Controller类,它重定向到带有学生列表的html页面
@Controller
public class TestController {
@Autowired
StudentService studentService;
@Autowired
PdfDemo pdfDemo;
@GetMapping("/test")
private String testPage(Model model)
{
List<Student> studentList = studentService.findAll();
System.out.println(studentList);
model.addAttribute(studentList);
return "sample";
}
}
这是我的html页面,显示学生列表
<body>
<div class="container" id="pdfDiv">
<h2>HTML Table</h2>
<table class="table table-striped">
<tr>
<th>Id</th>
<th>Name</th>
<th>Session</th>
<th>Department</th>
<th>Roll</th>
<th>Mobile</th>
</tr>
<tr th:each="student : ${studentList}">
<td th:text="${student.id}"></td>
<td th:text="${student.name}"></td>
<td th:text="${student.session}"></td>
<td th:text="${student.department}"></td>
<td th:text="${student.roll}"></td>
<td th:text="${student.mobile}"></td>
</tr>
</table>
</div>
<a href="#" th:href="@{/getStudentsListAsPdf}">Download PDF</a>
</body>
在这里您可以看到,我有一个生成pdf的链接。 PdfGenerateController
类是
@Controller
public class PdfGenerateController {
@GetMapping("/getStudentsListAsPdf")
public ResponseEntity<Resource> generateReportOfStudent() {
String downloadFilePath = generatePdfListForStudents();
System.out.println("DL File Path: "+downloadFilePath);
if (downloadFilePath == null)
throw new NullPointerException("data missing");
if (downloadFilePath == null)
return ResponseEntity.badRequest()
.contentType(MediaType.parseMediaType("application/pdf"))
.body(null);
File file = new File(downloadFilePath);
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource = null;
try {
resource = new ByteArrayResource(Files.readAllBytes(path));
} catch (IOException e) {
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=\"student_list" + ".pdf\"");
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}
}
这是编写代码以生成pdf的类
@Service
public class PdfDemo {
@Value("${file.download.base}")
private String DOWNLOAD_FOLDER;
public static final String DOWNLOAD_PATH = "tmp/downloads/";
public static final String ZIP_PATH = "/tmp/zip_files";
public static final String FILE_NAME = "student_list";
public static final String SERVER_REPORT_URL = "/report/html";
public static final String DOWNLOAD_FILE_PATH = DOWNLOAD_PATH + FILE_NAME;
public static final String ZIPFILE = "/tmp/zip_files/cmed_report.zip";
public static final String ZIPFILE_NAME = "cmed_report.zip";
public static final String SRCDIR = "/tmp/downloads";
public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd-HH";
public static String getBaseURL() throws MalformedURLException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
String baseUrl = "";
if (request != null) {
// handle proxy forward
String scheme = request.getScheme();
if (request.getHeader("x-forwarded-proto") != null) {
scheme = request.getHeader("x-forwarded-proto");
}
Integer serverPort = request.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
// No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
baseUrl = String.format("%s://%s%s", scheme, request.getServerName(), request.getContextPath());
} else {
baseUrl = String.format("%s://%s:%d%s", scheme, request.getServerName(), serverPort, request.getContextPath());
}
}
return baseUrl;
}
public static String generatePdfListForStudents()
{
WkHtmlToPdf pdf = new WkHtmlToPdf();
try {
pdf.addSources(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
System.out.println("Server absolute path: " + getServerAbsolutePath(SERVER_REPORT_URL));
System.out.println(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
} catch (Exception e) {
e.printStackTrace();
}
String downloadPath = DOWNLOAD_FILE_PATH + ".pdf";
pdf.addArguments(
Argument.from(EnableJavascript));
System.out.println("PDF Location: " + downloadPath);
// Save the PDF
File file = new File(downloadPath);
System.out.println("Directory status: " + file.exists() + " " + file.isDirectory());
try {
System.out.println("Paths.get: " + Paths.get(downloadPath));
pdf.save(Paths.get(downloadPath));
} catch (IOException e) {
e.printStackTrace();
}
return downloadPath;
}
public static String getServerAbsolutePath(String requestPath) throws MalformedURLException {
String URL = getBaseURL() + requestPath;
return URL;
}
}
这是Controller
类中SERVER_REPORT_URL
的{{1}}类
PdfDemo
现在,当我在HTML页面上点击@Controller
public class HtmlViewReportController {
@Autowired
StudentService studentService;
@GetMapping(value = "/report/html")
public String getPdfReportForStudent(Model model) {
model.addAttribute("studentList", studentService.findAll());
return "sample";
}
}
时,我得到了Download PDF
。错误堆栈跟踪在这里
error
这是github link。如果任何人都可以解决这个问题,将非常有帮助。
答案 0 :(得分:0)
我使用来自以下位置的Pdf对象以一种更简单的方式进行了操作
import com.github.jhonnymertz.wkhtmltopdf.wrapper.Pdf;
生成pdf看起来更容易,如下所示:
@Override
public String save(String url) throws IOException, InterruptedException{
Pdf pdf = new Pdf();
pdf.addPageFromUrl(url);
return mockSaveS3(pdf);
}
private String mockSaveS3(Pdf pdf) throws IOException, InterruptedException{
File fileTemp = File.createTempFile("pdf-", "");
File file = pdf.saveAs("apps/" + fileTemp.getName());
return file.getAbsolutePath();
}
然后我将Url返回到了我存储在apps/
目录中的PDF。
答案 1 :(得分:0)
我解决了这个问题。解决了很长时间。我在媒体上一步一步写了博客。我在这里发布该链接。您可以在此处查看所有步骤。我还提供了示例项目的github链接。看 here