2011-05-09 67 views
34

我希望我的Java应用程序在文件中编写HTML代码。现在,我很难用java.io.BufferedWriter类编码HTML标签。例如:使用Java编写HTML文件

BufferedWriter bw = new BufferedWriter(new FileWriter(file)); 
bw.write("<html><head><title>New Page</title></head><body><p>This is Body</p></body></html>"); 
bw.close(); 

有没有更简单的方法来做到这一点,因为我必须创建表格,它变得非常不方便?

回答

5

Velocity是写这类东西的好人选。
它允许你保持你的HTML和数据生成代码尽可能分开。

3

这真的取决于HTML文件正在创建的类型。

对于这样的任务,我使用创建一个对象,将其序列化为XML,然后使用XSL进行转换。这种方法的优点是:

  • 源代码和HTML模板之间的严格分离,
  • 而不必重新编译的应用程序来编辑的HTML的可能性,
  • 以服务在不同情况下不同的HTML的能力基于相同的XML,甚至在需要时直接提供XML(例如,用于进一步的反序列化),
  • 需要编写的较短的代码量。

的缺点是:

  • 你必须知道XSLT,并知道如何实现它在Java中。
  • 您必须编写XSLT(对许多开发人员来说这是一种折磨)。
  • 使用XSLT将XML转换为HTML时,某些部分可能会非常棘手。几个例子:<textarea/>标签(使页面无法使用),XML声明(可能导致IE问题),空格(使用<pre></pre>标签等),HTML实体(&nbsp;)等。
  • 性能会降低,因为到XML的序列化浪费了大量的CPU资源,而且XSL转换也非常昂贵。现在

,如果你的HTML很短或非常重复,或者如果HTML具有挥发性结构动态变化的,这种方法不能采取帐户。另一方面,如果您提供所有类似结构的HTML文件,并且希望减少Java代码和使用模板的数量,则此方法可能有效。

0

如果越来越重复的工作;我认为你可以做代码重用!为什么不简单地编写“写”HTML小块的函数呢?明白了吗?见例如。你可以有一个函数,你可以传递一个字符串,它会自动把它放到一个段落标记中并呈现它。当然,你也需要编写一些基本的解析器来完成这个任务(函数将如何知道该段落的附件!)。我不认为你是初学者..所以我没有详细说明...如果你不明白,请告诉我..

9

几个月前,我遇到了同样的问题,我发现每个库都提供了太多的功能,我最终目标的复杂性。所以我最终开发了自己的库 - HtmlFlow - 它提供了一个非常简单直观的API,它允许我以流畅的风格编写HTML。这里检查:https://github.com/fmcarvalho/HtmlFlow(它也支持动态绑定 HTML元素)

下面是一个Task对象的属性绑定到HTML元素的例子。考虑一个Task Java类具有三个属性:TitleDescriptionPriority,然后我们可以产生一个Task对象通过以下方式HTML文档:

import htmlflow.HtmlView; 

import model.Priority; 
import model.Task; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.PrintStream; 

public class App { 

    private static HtmlView<Task> taskDetailsView(){ 
     HtmlView<Task> taskView = new HtmlView<>(); 
     taskView 
       .head() 
       .title("Task Details") 
       .linkCss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"); 
     taskView 
       .body().classAttr("container") 
       .heading(1, "Task Details") 
       .hr() 
       .div() 
       .text("Title: ").text(Task::getTitle) 
       .br() 
       .text("Description: ").text(Task::getDescription) 
       .br() 
       .text("Priority: ").text(Task::getPriority); 
     return taskView; 
    } 

    public static void main(String [] args) throws IOException{ 
     HtmlView<Task> taskView = taskDetailsView(); 
     Task task = new Task("Special dinner", "Have dinner with someone!", Priority.Normal); 

     try(PrintStream out = new PrintStream(new FileOutputStream("Task.html"))){ 
      taskView.setPrintStream(out).write(task); 
      Desktop.getDesktop().browse(URI.create("Task.html")); 
     } 
    } 
} 
+1

一个不错的主意和一个不错的工具,但不幸的是,许可证不是很好,所以鼓励真正广泛的使用...;) – 2017-03-17 02:02:53

+0

@ s-n-ushakov对不起,我不是关于许可协议的专家。 GPL v3.0有什么问题? – 2017-03-17 10:39:20

+1

GPL的问题在于它太严格了。如果您只使用任何GPL授权代码,它都需要您透露GPL下的所有项目。这对爱好或大学编程可能没有问题,但对于与业务相关的编程而言,这可能是一个相当大的问题。为了让您的图书馆更加适合商业用途,我可能会建议将许可证至少更改为LGPL,而不要求您开放所有项目,但只需要向图书馆透露您的改进。其他许可证,也许稍微有点商业友好,是BSD,麻省理工学院,阿帕奇,Eclipse ... – 2017-03-18 05:17:37

28

如果你想自己做,不使用任何外部库,我觉得一个干净的方法是创建一个“template.html”文件的所有静态内容,例如像:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>$title</title> 
</head> 
<body>$body 
</body> 
</html> 

把类似$标签的标签对任何动态内容,然后做一些事情像这样:

File htmlTemplateFile = new File("path/template.html"); 
String htmlString = FileUtils.readFileToString(htmlTemplateFile); 
String title = "New Page"; 
String body = "This is Body"; 
htmlString = htmlString.replace("$title", title); 
htmlString = htmlString.replace("$body", body); 
File newHtmlFile = new File("path/new.html"); 
FileUtils.writeStringToFile(newHtmlFile, htmlString); 

注意:为简单起见,我使用org.apache.commons.io.FileUtils

+3

对于Java8,传递额外的Charset.forName(“UTF-8”),因为不带字符集的readFileToString已被弃用。 – 2016-10-09 17:03:47

+1

也可以使用MessageFormat进行替换:'String template = FileUtils.readFileToString(htmlTemplateFile); String title =“新页面”; String body =“This is Body”; String htmlString = MessageFormat.format(template,title,body);' 而'template'应该包含'{0}'为'title','{1}'为'body'。 – 2017-03-17 01:50:54

0

基于文档在内存中初步创建的模板和其他方法可能会对生成的文档大小施加一定的限制。

与此同时,一个非常简单和可靠的写上即时的方法来创建纯HTML的存在的基础上,SAX处理程序和默认XSLT转换器,HTML输出的后者有内在能力:

String encoding = "UTF-8"; 
FileOutputStream fos = new FileOutputStream("myfile.html"); 
OutputStreamWriter writer = new OutputStreamWriter(fos, encoding); 
StreamResult streamResult = new StreamResult(writer); 

SAXTransformerFactory saxFactory = 
    (SAXTransformerFactory) TransformerFactory.newInstance(); 
TransformerHandler tHandler = saxFactory.newTransformerHandler(); 
tHandler.setResult(streamResult); 

Transformer transformer = tHandler.getTransformer(); 
transformer.setOutputProperty(OutputKeys.METHOD, "html"); 
transformer.setOutputProperty(OutputKeys.ENCODING, encoding); 
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 

writer.write("<!DOCTYPE html>\n"); 
writer.flush(); 
tHandler.startDocument(); 
    tHandler.startElement("", "", "html", new AttributesImpl()); 
     tHandler.startElement("", "", "head", new AttributesImpl()); 
      tHandler.startElement("", "", "title", new AttributesImpl()); 
       tHandler.characters("Hello".toCharArray(), 0, 5); 
      tHandler.endElement("", "", "title"); 
     tHandler.endElement("", "", "head"); 
     tHandler.startElement("", "", "body", new AttributesImpl()); 
      tHandler.startElement("", "", "p", new AttributesImpl()); 
       tHandler.characters("5 > 3".toCharArray(), 0, 5); // note '>' character 
      tHandler.endElement("", "", "p"); 
     tHandler.endElement("", "", "body"); 
    tHandler.endElement("", "", "html"); 
tHandler.endDocument(); 
writer.close(); 

请注意,XSLT转换器将免除您摆脱特殊字符(如>)的负担,因为它本身需要处理它。

它是容易将保鲜膜SAX方法,如startElement()characters()到一个人的口味的东西更方便......

2

您可以使用jsoupwffweb(HTML5)为主。对于jsoup

示例代码: -

Document doc = Jsoup.parse("<html></html>"); 
doc.body().addClass("body-styles-cls"); 
doc.body().appendElement("div"); 
System.out.println(doc.toString()); 

打印为wffweb

<html> 
<head></head> 
<body class=" body-styles-cls"> 
    <div></div> 
</body> 
</html> 

示例代码: -

Html html = new Html(null) {{ 
    new Head(this); 
    new Body(this, 
     new ClassAttribute("body-styles-cls")); 
}}; 

Body body = TagRepository.findOneTagAssignableToTag(Body.class, html); 
body.appendChild(new Div(null)); 

System.out.println(html.toHtmlString()); 
//directly writes to file 
html.toOutputStream(new FileOutputStream("/home/user/filepath/filename.html"), "UTF-8"); 

打印(在缩小的格式): -

<html> 
<head></head> 
<body class="body-styles-cls"> 
    <div></div> 
</body> 
</html>