2011-05-09 68 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>